En esta nueva etapa como Golang lover, se me pasó por la cabeza aplicar un enfoque funcional a mi código en Golang.
Realmente, no estoy del todo seguro si aplicarlo producción y si realmente puede aplicar y hacer todo mas legible y escaladle. Pero aquí tenéis las ultimas pruebas aplicando el patron option.
Option pattern
Realmente es bastante sencillo el enfoque y a la vez nos ofrece una clara backward compatibility interesante, pero tenemos que saber qué viene con un poco de overhead a la hora de generar estructuras nuevas.
Para aplicar este patron, primero definimos nuestra estructura a la cual le queremos definir este patrón.
type CLI struct {
name string
args []string
}
Una vez tenemos definida la estructura, creamos otro tipo que por convencion, suele tener el nombre de Option
type Option func(*CLI)
Ya tenemos lo necesario para comenzar con el overhead de funciones, en el ejemplo que he puesto, podría ser:
func WithArg(arg string) Option {
return func(c *CLI) {
c.args = append(c.args, arg)
}
}
func WithName(name string) Option {
return func(c *CLI) {
c.name = name
}
}
Llegados a este punto, creamos el constructor teniendo en cuenta la implementacion
func New(options ...Option) CLI {
c := &CLI{}
for _, o := range options {
o(c)
}
return *c
}
Y ya tenemos nuestro primer patron Option picado para ser usado
Código completo
package main
import "fmt"
type CLI struct {
name string
args []string
}
type Option func(*CLI)
func WithArg(arg string) Option {
return func(c *CLI) {
c.args = append(c.args, arg)
}
}
func WithName(name string) Option {
return func(c *CLI) {
c.name = name
}
}
func New(options ...Option) CLI {
c := &CLI{}
for _, o := range options {
o(c)
}
return *c
}
func main() {
cli := New(
WithArg("arg 1"),
WithArg("arg 2"),
WithName("Name"),
)
fmt.Printf("Args: %+v\n", cli.args)
fmt.Printf("Name: %+s\n", cli.name)
}