Patrones de dise帽o en Go - Abstract Factory

隆Hola, Habr! Les presento la traducci贸n del pr贸ximo art铆culo "Patrones de dise帽o: Patr贸n abstracto de f谩brica" de Shubham Zanwar.

Una f谩brica abstracta es un patr贸n de dise帽o generativo. Se utiliza cuando necesitamos crear una familia de productos similares. Tomemos un ejemplo de una cadena de pizzas para entenderlo.

Pizzer铆a

Digamos que eres el jefe de un negocio y abres una cadena de pizzer铆as por toda la ciudad. Una de sus responsabilidades es la elaboraci贸n de todos los productos principales (en nuestro caso, pizzas y pan de ajo frito), que estar谩n representados por marcas como Domino y Roaster.

Hay muchas maneras de hacer esto. Lo m谩s f谩cil es crear una f谩brica de pizzas para cada marca y otra similar para pan frito.

Si a煤n no tiene idea de c贸mo funcionan las f谩bricas, puede leer aqu铆

El problema es que ahora confiamos en que el usuario elija el tipo correcto de pizza y pan tostado que desee. Si cometen el error de hacer Domino's Pizza con pan de ajo tostado, sus clientes se pondr谩n furiosos y usted podr铆a perder su contrato con estas marcas.

, .

( ), . .

, , .

. , :

type iPizza interface {
    GetPrice() float64
    GetName() string
    GetToppings() []string
}

type pizza struct {
    name     string
    price    float64
    toppings []string
}

func (p *pizza) GetName() string {
    return p.name
}

func (p *pizza) GetPrice() float64 {
    return p.price
}

func (p *pizza) GetToppings() []string {
    return p.toppings
}

type pizzaHutPizza struct {
    pizza
}

type dominosPizza struct {
    pizza
}

type iGarlicBread interface {
    GetPrice() float64
    GetName() string
}

type garlicBread struct {
    name  string
    price float64
}

func (g *garlicBread) GetName() string {
    return g.name
}

func (g *garlicBread) GetPrice() float64 {
    return g.price
}

type pizzaHutGarlicBread struct {
    garlicBread
}

type dominosGarlicBread struct {
    garlicBread
}

, , . .

,

type iPizzaFactory interface {
    createPizza() iPizza
    createGarlicBread() iGarlicBread
}

: - -

type PizzaHutFactory struct {}

func (p *PizzaHutFactory) createPizza(): iPizza {
    return &pizzaHutPizza{
        pizza{
            name:     "pepperoni",
            price:    230.3,
            toppings: []string{"olives", "mozzarella", "pork"},
        },
    }
}

func (p *pizzaHutFactory) createGarlicBread() iGarlicBread {
    return &pizzaHutGarlicBread{
        garlicBread{
            name:  "garlic bread",
            price: 180.99,
        },
    }
}
type dominosFactory struct{}

func (d *dominosFactory) createPizza() iPizza {
    return &dominosPizza{
        pizza{
            name:     "margherita",
            price:    200.5,
            toppings: []string{"tomatoes", "basil", "olive oil"},
        },
    }
}

func (d *dominosFactory) createGarlicBread() iGarlicBread {
    return &dominosGarlicBread{
        garlicBread{
            name:  "cheesy bread sticks",
            price: 150.00,
        },
    }
}

, /.

. , . ? .

. , ( ), ( ). "", .

-

func getPizzaFactory(chain string) (iPizzaFactory, error) {
    if chain == "P" {
        return &pizzaHutFactory{}, nil
    }
    if chain == "D" {
        return &dominosFactory{}, nil
    }
    return nil, fmt.Errorf("Enter a valid chain type next time")
}

, .

Lo principal para recordar es que el patr贸n de f谩brica abstracto implementa una f谩brica de f谩brica. Las f谩bricas internas se utilizan para crear el tipo adecuado de productos.

Puedes encontrar este c贸digo en github

Mientras




All Articles