Olá, Habr! Apresento a sua atenção a tradução do próximo artigo "Design Patterns: Abstract Factory Pattern", de Shubham Zanwar.
Uma fábrica abstrata é um padrão de design generativo. É usado quando precisamos criar uma família de produtos semelhantes. Vamos dar um exemplo de uma rede de pizza para compreensão.
Pizzaria
Digamos que você seja o chefe de uma empresa e abra uma rede de pizzarias pela cidade. Uma das suas responsabilidades é a produção de todos os produtos básicos (no nosso caso, pizzas e pão de alho frito), que serão representados por marcas como Domino e Roaster (vamos chamá-los assim - aprox. Transl.).
Existem muitas maneiras de fazer isso. O mais fácil é criar uma fábrica de pizza para cada marca e uma fábrica semelhante de pão frito.
Se você ainda não tem ideia de como as fábricas funcionam, pode ler aqui
O problema é que agora confiamos no usuário para escolher o tipo certo de pizza e pão torrado que deseja. Se cometerem o erro de fazer pizza Domino's com pão de alho Frypot, seus clientes ficarão furiosos e você poderá perder o contrato com essas 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")
}, .
A principal coisa a lembrar é que o padrão de fábrica abstrato implementa uma fábrica de fábrica. Fábricas internas são usadas para criar produtos do tipo desejado.
Você pode encontrar este código no github
Enquanto