Todavía estoy tratando de entender los patrones de diseño aquí, después de aprender el patrón abstracto de fábrica, me di cuenta de que este patrón no escalará bien. Echa un vistazo al diagrama uml del patrón abstracto de fábrica
Si tengo que crear un nuevo 'AbstractProductC', tendré que agregar un método abstracto 'CreateProductC' en 'AbstractFactory' que afecta la implementación de ConcreateFactory1, ConcreateFactory2.
Mi pregunta aquí es, ¿el patrón de Abstract Factory se escala en absoluto (o) estoy pensando en la dirección incorrecta aquí?
gracias por adelantado
design
design-patterns
Jitendar
fuente
fuente
Respuestas:
Abstract Factory escala muy bien.
Hay un principio básico que establece que una clase debe hacer una cosa bien. Su problema aquí es que está tratando de hacer que muchas clases hagan muchas cosas.
No tiene que atenerse a una fábrica abstracta. Puede (y debe tener) varios:
AbstractProductAFactory
define la interfaz para producir ProductA. Sus implementaciones concretas (ConcreteProductAFactory1, ConcreteProductAFactory2) lo ampliarían.AbstractProductBFactory
define la interfaz para producir ProductB. Sus implementaciones concretas (ConcreteProductBFactory1
,ConcreteProductBFactory2
) lo ampliarían.Si necesita un ProductC, cree uno nuevo
AbstractProductCFactory
. No es necesario cambiar ninguna de sus otras fábricas de esta manera.ACTUALIZACIÓN Idealmente, ProductA debería representar una clase de producto, es decir, todos los productos que comparten una interfaz que está llamando ProductA. En los comentarios sugiero que esto es algo así como una pizza:
Y así. Agregar una PanPizzaFactory no afectará a ninguna de las otras clases: es solo una nueva implementación concreta de PizzaFactory. Si tiene productos que no son pizzas, por ejemplo, sándwiches, allí es donde crea otra fábrica abstracta (por ejemplo,
AbstractSandwichFactory
).El punto real es que no querrás tener una fábrica abstracta que construya dos tipos muy diferentes de productos con dos métodos diferentes de "compilación". Agrúpelos lo más lógicamente posible para que compartan una interfaz, y luego cree una fábrica abstracta que defina cómo las fábricas concretas deben construir implementaciones de esa interfaz.
fuente
AbstractPizzaFactory.buildPizza(List<Topping> toppings)
.El problema con el escalado es que el código puede escalar de muchas maneras diferentes. El problema que tiene es simplemente causado por la necesidad de escalar en una dirección, ese patrón de diseño no está destinado. En el caso del patrón Abstract Factory, está destinado a escalar para agregar nuevas fábricas de concreto, pero agregar nuevos productos causa grandes cambios estructurales.
Uno de los puntos del diseño y la arquitectura del software es identificar las direcciones más probables que el código escalará y seleccionará patrones basados en esas direcciones probables. Si se identifica, es más probable que agregue un nuevo producto que agregar una nueva fábrica de concreto, entonces usar Abstract Factory no es una buena idea y podría ser mejor repensar completamente el diseño.
fuente
Sí, tiene razón, la "fábrica abstracta" no escala bien cuando necesita productos abstractos adicionales .
Pero en muchos escenarios del mundo real, tiene una cantidad cambiante de productos, pero solo una cantidad pequeña y fija de productos abstractos para admitir. Por ejemplo, tome el ejemplo de widgets GUI del artículo de Wikipedia sobre fábricas abstractas . La fábrica de GUI abstracta podría tener un método
createWidget
(en lugar decreateButton
), donde seWidget
encuentra el "producto abstracto", siendo la clase base más alta para una familia de varias docenas de elementos de GUI. Agregar nuevos widgets GUI de ninguna manera implica un cambio en la interfaz de la fábrica abstracta, por lo que no se debe cambiar ninguna de las interfaces de la fábrica concreta.Tener muchos productos abstractos significa que tendrá muchas jerarquías de clases diferentes en su código. Y si ese es el caso, puede considerar crear una fábrica individual (o fábrica abstracta) para cada una de las jerarquías.
fuente
Su factor de escala es una simple cuestión de gestión de dependencias. Cuantas más dependencias tenga una clase, más estable y reflexiva debería ser su API.
No hay ningún problema en crear una fábrica que esté definida por la responsabilidad de crear tipos de naturaleza similar o cohesiva. Pero cuantas más clases dependan de esta fábrica, más estricta debería ser esta cohesión.
(Nota: esto se puede hacer de manera gradual, no necesariamente por un BDUF)
fuente