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