REBAJA de primavera
Factory Method

Factory Method en Go

Factory method es un patrón de diseño creacional que resuelve el problema de crear objetos de producto sin especificar sus clases concretas.

El patrón Factory Method define un método que debe utilizarse para crear objetos, en lugar de una llamada directa al constructor (operador new). Las subclases pueden sobrescribir este método para cambiar las clases de los objetos que se crearán.

Si no sabes la diferencia entre varios patrones y conceptos de la fábrica, lee nuestra Comparación de fábricas.

Ejemplo conceptual

Resulta imposible implementar el clásico patrón Factory Method en Go debido a la falta de funciones POO, como las clases y la herencia. Sin embargo, podemos implementar la versión básica del patrón, el Simple Factory.

En este ejemplo, vamos a crear varios tipos de armas utilizando una estructura de fábrica.

Primero, creamos la interfaz iGun, que define todos los métodos con los que debería contar un arma. Hay un tipo de estructura gun que implementa la interfaz iGun. Dos armas concretas (ak47 y musket), ambas integran la estructura del arma e, indirectamente, implementan todos los métodos iGun.

La estructura gunFactory sirve como fábrica, que crea armas del tipo deseado en base a un argumento entrante. main.go actúa como cliente. En lugar de interactuar directamente con ak47 o musket, se basa en gunFactory para crear instancias de varias armas, utilizando únicamente parámetros de cadenas para controlar la producción.

iGun.go: Interfaz de producto

package main

type IGun interface {
	setName(name string)
	setPower(power int)
	getName() string
	getPower() int
}

gun.go: Producto concreto

package main

type Gun struct {
	name  string
	power int
}

func (g *Gun) setName(name string) {
	g.name = name
}

func (g *Gun) getName() string {
	return g.name
}

func (g *Gun) setPower(power int) {
	g.power = power
}

func (g *Gun) getPower() int {
	return g.power
}

ak47.go: Producto concreto

package main

type Ak47 struct {
	Gun
}

func newAk47() IGun {
	return &Ak47{
		Gun: Gun{
			name:  "AK47 gun",
			power: 4,
		},
	}
}

musket.go: Producto concreto

package main

type musket struct {
	Gun
}

func newMusket() IGun {
	return &musket{
		Gun: Gun{
			name:  "Musket gun",
			power: 1,
		},
	}
}

gunFactory.go: Fábrica

package main

import "fmt"

func getGun(gunType string) (IGun, error) {
	if gunType == "ak47" {
		return newAk47(), nil
	}
	if gunType == "musket" {
		return newMusket(), nil
	}
	return nil, fmt.Errorf("Wrong gun type passed")
}

main.go: Código cliente

package main

import "fmt"

func main() {
	ak47, _ := getGun("ak47")
	musket, _ := getGun("musket")

	printDetails(ak47)
	printDetails(musket)
}

func printDetails(g IGun) {
	fmt.Printf("Gun: %s", g.getName())
	fmt.Println()
	fmt.Printf("Power: %d", g.getPower())
	fmt.Println()
}

output.txt: Resultado de la ejecución

Gun: AK47 gun
Power: 4
Gun: Musket gun
Power: 1

Factory Method en otros lenguajes

Factory Method en C# Factory Method en C++ Factory Method en Java Factory Method en PHP Factory Method en Python Factory Method en Ruby Factory Method en Rust Factory Method en Swift Factory Method en TypeScript