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)
}

Deja una respuesta