2010-04-24 10 views
6

Estoy tratando de entender el patrón de diseño de fábrica.beneficio de tener una fábrica para la creación de objetos?

No entiendo por qué es bueno tener un intermediario entre el cliente y el producto (objeto que el cliente quiere).

ejemplo, con ninguna fábrica:

$mac = new Mac(); 

ejemplo, con una fábrica:

$appleStore = new AppleStore(); 
$mac = $appleStore->getProduct('mac'); 

¿Cómo el patrón de la fábrica desacoplar el cliente del producto?

¿Podría alguien dar un ejemplo de un cambio de código futuro que tendrá un impacto negativo en el ejemplo 1, pero positivo en el ejemplo 2, por lo que entiendo la importancia del desacoplamiento?

Gracias.

+1

¿Ese segundo parece más una relación que una fábrica para mí ...? – SeanJA

Respuesta

5

Creo que tiene que ver con los recursos necesarios para la construcción de algunos tipos de objetos.

De manera informal, si le pedía a alguien que construyera una Mac, sería un proceso laborioso que tomaría años de diseño, desarrollo, fabricación y pruebas, y podría no hacerse bien. Este proceso debería repetirse para cada Mac. Sin embargo, si introduce una fábrica, todo el trabajo duro se puede hacer solo una vez, y luego las Mac pueden producirse de forma más económica.

Ahora considere Joomla's factory.php. Por lo que puedo decir, el objetivo principal de JFactory es agrupar objetos y asegurarse de que los objetos que deberían ser iguales no se copien. Por ejemplo, JFactory::getUser() devolverá una referencia a uno y solo un objeto. Si algo cambia en ese objeto de usuario, aparecerá en todas partes. Además, tenga en cuenta que JFactory::getUser() devuelve una referencia, no un objeto nuevo. Eso es algo que simplemente no puedes hacer con un constructor.

A menudo, necesita contexto local al construir un objeto, y ese contexto puede persistir y posiblemente tomar muchas formas. Por ejemplo, puede haber una base de datos MySQL que contenga a los usuarios. Si los objetos de usuario se crean con un constructor, tendrá que pasar un objeto de base de datos al constructor (o hacer que dependa de una variable global). Si decide cambiar su aplicación a PostgreSQL, la semántica del objeto Base de datos puede cambiar, lo que hace que todos los usos del constructor necesiten revisión. Las variables globales nos permiten ocultar esos detalles, al igual que las fábricas. Por lo tanto, una fábrica de Usuario desacoplaría los detalles de la construcción de objetos de Usuario desde lugares donde se necesitan objetos de Usuario.

¿Cuándo son útiles las fábricas? Cuando se construye un objeto, se requieren detalles de fondo. ¿Cuándo son mejores los constructores? Cuando las variables globales son suficientes.

+1

+1 analogía de bonificación – SeanJA

+0

pero esto no se llama "mover el proceso a un lugar central". lo que no entiendo es la palabra desacoplar. –

+0

pero si necesito cambiar la base de datos y estoy utilizando la fábrica, todavía tengo que cambiar mi código en la fábrica. es esta parte que no entiendo del todo. De cualquier manera tengo que cambiar, ahora solo lo moví a otra clase, la fábrica. Puedo entender que esto es bueno si se trata de aplicaciones frameworks/os. sus usuarios que interactúan con su código no tienen que volver a escribir su código. pero si soy el único que estoy usando el código que escribo, ¿cómo es mejor la fábrica? todavía tengo que cambiar si cambio la base de datos. –

1

En este ejemplo se devuelve un objeto de tipo Mac y nunca puede ser algo diferente:

$mac = new Mac(); 

No puede ser una subclase de Mac, no puede ser de una clase que coincide con la interfaz de Mac.

Considerando que el ejemplo siguiente puede devolver un objeto de tipo Mac o cualquier otro tipo que la fábrica decida es apropiado.

$appleStore = new AppleStore(); 
$mac = $appleStore->getProduct('mac'); 

Es posible que desee un conjunto de subclases de Mac, cada uno representando un modelo diferente de Mac. Luego, escribe el código en la fábrica para decidir cuál de estas subclases usar. No puede hacer eso con el operador new.

Así que una fábrica le da más flexibilidad en la creación de objetos. La flexibilidad a menudo va de la mano con el desacoplamiento.


Re tu comentario: Yo no diría que no uso new. De hecho, utilizo new para la mayoría de la creación de objetos simples. Pero no tiene nada que ver con quién escribe el código del cliente. El patrón de fábrica es para cuando desea una arquitectura que puede elegir la clase para instanciar dinámicamente.

En su ejemplo de Apple Store, es probable que desee un código simple para instanciar un producto y agregarlo a un carrito de compras. Si usa new y tiene diferentes tipos de objetos para cada tipo de producto diferente, tendrá que escribir una declaración enorme case para que pueda crear un objeto new del tipo apropiado. Cada vez que agregue un tipo de producto, deberá actualizar esa declaración case. Y es posible que tenga varias de estas declaraciones case en otras partes de su aplicación.

Al usar una fábrica, solo tendría un lugar para actualizar, que sabe cómo tomar un parámetro y crear instancias del tipo correcto de objeto. Todos los lugares de su aplicación obtendrían soporte implícito para el nuevo tipo, sin necesidad de cambios de código. Este es un triunfo ya sea que usted sea el único desarrollador o si está en un equipo.

Pero una vez más, no necesita una fábrica si no necesita admitir una variedad de subtipos. Simplemente continúe usando new en casos simples.

+0

, entonces el foco está en "¿cómo puedo escribir código para que cada vez que cambie mi código, el CLIENTE no tenga que hacerlo"? así que, básicamente, NUNCA deseo que el cliente use productos nuevos en los "productos finales". Quiero proporcionar una capa de abstracción (fábrica) para la creación de productos. entonces, ¿no tiene que saber qué sucede detrás de escena? ¿Estoy en lo correcto? pero ¿qué pasa cuando codigo todo yo mismo? De cualquier manera, tengo que cambiar. No entiendo dónde se encuentra el foco o lo que quiero hacer como desarrollador. –

Cuestiones relacionadas