Comprende las diferencias en las motivaciones:
Suponga que está construyendo una herramienta donde tiene objetos y una implementación concreta de las interrelaciones de los objetos. Como prevé variaciones en los objetos, ha creado una indirección al asignar la responsabilidad de crear variantes de los objetos a otro objeto ( lo llamamos fábrica abstracta ). Esta abstracción encuentra un gran beneficio ya que prevé futuras extensiones que necesitarán variantes de esos objetos.
Otra motivación bastante intrigante en esta línea de pensamiento es un caso en el que todos o ninguno de los objetos de todo el grupo tendrán una variante correspondiente. Según algunas condiciones, se utilizará cualquiera de las variantes y en cada caso todos los objetos deben ser de la misma variante. Esto podría ser un poco contra intuitivo de entender, ya que a menudo tendemos a pensar que, siempre y cuando las variantes de un objeto sigan un contrato uniforme común ( interfaz en sentido más amplio ), el código de implementación concreto nunca debería romperse. El hecho intrigante aquí es que, no siempre esto es cierto, especialmente cuando el comportamiento esperado no puede ser modelado por un contrato de programación.
Un simple ( tomando prestada la idea de GoF ) es cualquier aplicación GUI que diga un monitor virtual que emule la apariencia de MS o Mac o Fedora OS. Aquí, por ejemplo, cuando todos los objetos de widgets como ventanas, botones, etc. tienen una variante MS, excepto una barra de desplazamiento que se deriva de la variante MAC, el propósito de la herramienta falla gravemente.
Estos casos anteriores forman la necesidad fundamental de Abstract Factory Pattern .
Por otro lado, imagine que está escribiendo un marco para que muchas personas puedan construir varias herramientas ( como la de los ejemplos anteriores ) utilizando su marco. Por la sola idea de un marco, no es necesario, aunque no pueda usar objetos concretos en su lógica. Prefieres poner algunos contratos de alto nivel entre varios objetos y cómo interactúan. Si bien usted ( como desarrollador de framework ) permanece en un nivel muy abstracto, cada constructor de la herramienta se ve obligado a seguir sus construcciones de framework. Sin embargo, ellos ( los creadores de herramientas ) tienen la libertad de decidir qué objeto construir y cómo interactuarán todos los objetos que crean. A diferencia del caso anterior ( de Abstract Factory Pattern ), usted ( como creador del framework) no es necesario trabajar con objetos concretos en este caso; y más bien puede permanecer en el nivel de contrato de los objetos. Además, a diferencia de la segunda parte de las motivaciones anteriores, usted o los constructores de herramientas nunca tienen la situación de mezclar objetos de variantes. Aquí, mientras el código marco permanece en el nivel de contrato, cada constructor de herramientas está restringido ( por la naturaleza del caso mismo ) a usar sus propios objetos. Las creaciones de objetos en este caso se delegan a cada implementador y los proveedores de marcos solo proporcionan métodos uniformes para crear y devolver objetos. Dichos métodos son inevitables para que el desarrollador de marcos continúe con su código y tiene un nombre especial llamado Método de fábrica ( Patrón de método de fábrica para el patrón subyacente ).
Pocas notas:
- Si está familiarizado con el 'método de plantilla', verá que los métodos de fábrica a menudo se invocan a partir de métodos de plantilla en el caso de programas pertenecientes a cualquier forma de marco. Por el contrario, los métodos de plantilla de los programas de aplicación son a menudo simples implementaciones de algoritmos específicos y sin métodos de fábrica.
- Además, para la integridad de los pensamientos, utilizando el marco ( mencionado anteriormente ), cuando un constructor de herramientas está construyendo una herramienta, dentro de cada método de fábrica, en lugar de crear un objeto concreto, él / ella puede delegar aún más la responsabilidad a un resumen -fabricante de objetos, siempre que el constructor de herramientas prevea variaciones de los objetos concretos para futuras extensiones.
Código de muestra:
//Part of framework-code
BoardGame {
Board createBoard() //factory method. Default implementation can be provided as well
Piece createPiece() //factory method
startGame(){ //template method
Board borad = createBoard()
Piece piece = createPiece()
initState(board, piece)
}
}
//Part of Tool-builder code
Ludo inherits BoardGame {
Board createBoard(){ //overriding of factory method
//Option A: return new LudoBoard() //Lodu knows object creation
//Option B: return LudoFactory.createBoard() //Lodu asks AbstractFacory
}
….
}
//Part of Tool-builder code
Chess inherits BoardGame {
Board createBoard(){ //overriding of factory method
//return a Chess board
}
….
}