pattern method design-patterns factory factory-pattern factory-method static-factory

design-patterns - method - builder pattern



Factory Pattern-CreateInstance estático o no? (3)

Esto es sobre el patrón de fábrica. Estoy un poco confundido.

Vi implementaciones donde el método createInstance() es estático y algunas implementaciones que no son estáticas.

Algunos dicen que depende de "estilo" o "gusto" y algunos dicen que no. Wikipedia dice que no debe ser estático, y http://www.dofactory.com/Patterns/PatternFactory.aspx también dice que no debería ser estático, según The Gang of Four.

Mi pregunta es: ¿depende del estilo y el gusto o viola el patrón de fábrica si se implementa de manera estática? ¿Lo que es correcto?


Dudo mucho en categorizar "instancia versus estática" como una cuestión de gusto. Esto implica que es estético como un color favorito o, más apropiado, camelCase frente a PascalCase.

Instancia versus estática es más una cuestión de concesiones. Con miembros de instancia de cualquier tipo, obtienes todos los beneficios del polimorfismo, ya que puedes implementar interfaces y heredar de otras clases cuando tienes instancias y miembros de instancias. Con estática, no obtienes estos beneficios. En general, la estática frente a la instancia es una compensación para la simplicidad inicial frente a la simplicidad aguas abajo. La estática es fácil porque es accesible a nivel mundial y no tiene que considerar cosas como "¿cuándo debería ser instanciado y por quién?" No tiene que pasarlos con accesors / mutators o constructores, y su API se ve más limpia. Esto facilita el razonamiento inicial. Pero hace el mantenimiento y las implementaciones futuras más difíciles.

Si tienes un método estático, digamos un método de fábrica en tu caso, y luego quieres que se comporte de manera diferente en ciertas situaciones, eres como una manguera. Tienes que hacer un segundo método y copiar y pegar la funcionalidad menos lo que quieras cambiar, y luego hacer que los clientes lo resuelvan. O, lo que es peor, expones una variable global y haces que los clientes establezcan esto antes y después de usar tu método, mientras que el método global indica al comportamiento cómo comportarse.

Si hubiera seguido la ruta de instancia por adelantado, sería fácil. Simplemente heredará y anulará su método de fábrica inicial y proporcionará las clases derivadas donde necesite la nueva funcionalidad. No está imponiendo una carga adicional al código del cliente y casi no hace modificaciones a las clases existentes (principio abierto / cerrado).

Mi consejo sería hacerle un favor a usted y / u otros mantenedores y usar la implementación de la instancia. No es una cuestión de lo que la Banda de los Cuatro o cualquier otra persona quiere o prefiere; es cuestión de tu propia cordura ante la podredumbre del código.


Si es una abstract factory nivel de instancia es normal. Y la funcionalidad de nivel de instancia tiende a ser más fácil de simular y prueba de unidad que static nivel static


El método estático no viola el patrón pero va en contra de muchas otras prácticas orientadas a objetos (inversión de control + inyección de dependencia como un ejemplo) por lo que el uso de instancias es mejor.

Editar:

Acabo de obtener una insignia para esta respuesta, pero cuando la leí no pude creer lo que veía. Está mal cuando hablamos estrictamente sobre el patrón de método GoF Factory y merece alguna corrección.

Puede tener el método estático CreateInstance para crear una instancia de un tipo; no hay nada de malo en eso; a menudo la gente lo llama método de fábrica, pero eso no es lo que se llama patrón de método de fábrica. Una vez que empiezas a poner la lógica en este método para crear instancias de diferentes tipos dependiendo de alguna condición, es posible que necesites un patrón de método de fábrica descrito por GoF.

El objetivo del patrón de método GoF Factory es reemplazar la lógica condicional dentro de CreateInstance con herencia y polimorfismo y, por lo tanto, no puede ser estática. El método de fábrica es un método de instancia; además, es virtual. Su tipo base tiene generalmente CreateInstance abstracta y la lógica condicional se reemplaza por el árbol de herencia donde cada subtipo anula CreateInstance y crea un producto específico para ese subtipo.