Ainda estou tentando entender os padrões de design aqui, depois de aprender o padrão abstrato de fábrica, percebi que esse padrão não será dimensionado bem. Dê uma olhada no diagrama uml do padrão abstrato de fábrica
Se eu tiver que criar um novo 'AbstractProductC', terei que adicionar um método abstrato 'CreateProductC' em 'AbstractFactory', que afeta a implementação do ConcreateFactory1, ConcreateFactory2.
Minha pergunta aqui é: o padrão Abstract Factory é escalado de alguma forma (ou) eu estou pensando na direção errada aqui?
desde já, obrigado
design
design-patterns
Jitendar
fonte
fonte
Respostas:
Abstract Factory escala muito bem.
Existe um princípio básico que afirma que uma classe deve fazer uma coisa bem. Seu problema aqui é que você está tentando fazer com que muitas classes façam muitas coisas.
Você não precisa se ater a uma fábrica abstrata. Você pode (e deve ter) vários:
AbstractProductAFactory
define a interface para produzir o ProductA. Suas implementações de concreto (ConcreteProductAFactory1, ConcreteProductAFactory2) a estenderiam.AbstractProductBFactory
define a interface para produzir o ProductB. Suas implementações concretas (ConcreteProductBFactory1
,ConcreteProductBFactory2
) a estenderiam.Se você precisar de um ProductC, crie um novo
AbstractProductCFactory
. Não é necessário alterar nenhuma de suas outras fábricas dessa maneira.ATUALIZAÇÃO Idealmente, o ProductA deve representar uma classe de produto - ou seja, todos os produtos que compartilham uma interface que você está chamando de ProductA. Nos comentários, sugiro que isso é algo como uma Pizza:
E assim por diante. Adicionar um PanPizzaFactory não afetará nenhuma das outras classes - é apenas uma nova implementação concreta do PizzaFactory. Se você tem produtos que não são pizzas - sanduíches, por exemplo, é aí que você cria outra fábrica abstrata (por exemplo,
AbstractSandwichFactory
).O ponto real é que você não gostaria de ter uma fábrica abstrata que constrói dois tipos muito diferentes de produto com dois métodos diferentes de "construção". Agrupe-os da maneira mais lógica possível, para que eles compartilhem uma interface e, em seguida, crie uma fábrica abstrata que defina como fábricas concretas devem construir implementações dessa interface.
fonte
AbstractPizzaFactory.buildPizza(List<Topping> toppings)
.O problema com a escala é que o código pode ser escalado de várias maneiras diferentes. O problema que você está enfrentando é simplesmente causado pela necessidade de escalar em uma direção, para o qual o padrão de design não se destina. No caso do padrão Abstract Factory, ele deve ser dimensionado de forma a adicionar novas fábricas de concreto, mas adicionar novos produtos causa grandes mudanças estruturais.
Um dos pontos do design e da arquitetura de software é identificar as direções mais prováveis para o código escalar e escolher padrões com base nessas direções prováveis. Se você identificar que a adição de um novo produto é mais provável do que a adição de uma nova fábrica de concreto, usar a Abstract Factory não é uma boa ideia e pode ser melhor repensar completamente o design.
fonte
Sim, você está certo, a "fábrica abstrata" não se adapta bem quando você precisa de produtos abstratos adicionais .
Mas em muitos cenários do mundo real, você tem um número variável de produtos, mas apenas um número pequeno e fixo de produtos abstratos para oferecer suporte. Por exemplo, veja o exemplo de widgets da GUI no artigo da Wikipedia sobre fábricas abstratas . A fábrica abstrata da GUI poderia ter um método
createWidget
(em vez decreateButton
), ondeWidget
é o "produto abstrato", sendo a classe base mais alta para uma família de várias dezenas de elementos da GUI. A adição de novos widgets da GUI não implica em nenhuma alteração na interface da fábrica abstrata, portanto, nenhuma das interfaces da fábrica de concreto precisa ser alterada.Ter muitos produtos abstratos significa que você terá várias hierarquias de classe diferentes no seu código. E se for esse o caso, considere criar uma fábrica individual (ou fábrica abstrata) para cada uma das hierarquias.
fonte
Seu fator de escala é uma questão simples de gerenciamento de dependências. Quanto mais dependências uma classe tiver - mais estável e ponderada deverá ser sua API.
Não há problema em criar uma fábrica definida pela responsabilidade de criar tipos de natureza semelhante ou coesa. Mas quanto mais classes dependem dessa fábrica - mais estrita deve ser essa coesão.
(Nota: isso pode ser feito de forma gradual, não necessariamente por um BDUF)
fonte