2010-03-04 14 views
7

¿El Factory Method pattern (que no debe confundirse con los patrones Factory o Abstract Factory) infringe el Open/Closed principle?¿El patrón de método de fábrica viola el principio de abierto/cerrado?

Actualización: Para aclarar, me refiero al escenario en el que una clase concreta tiene métodos de fábrica estáticos. Por ejemplo (esto es de la página de Wikipedia sobre FMP):

class Complex 
{ 
    public static Complex fromCartesian(double real, double imag) { 
     return new Complex(real, imag); 
    } 

    public static Complex fromPolar(double modulus, double angle) { 
     return new Complex(modulus * cos(angle), modulus * sin(angle)); 
    } 

    private Complex(double a, double b) { 
     //... 
    } 
} 

qué no el constructor privado impedir que la clase de ser una subclase, es decir, extendida?

¿No habría que modificar la clase para admitir nuevos métodos de fábrica? Por ejemplo, si la clase inicialmente solo tenía Cartesian y luego fromPolar, ¿no era necesario modificar la clase para admitir esto?

¿No violan estos dos abiertos/cerrados?

+2

Me gustaría saber qué piensas de esto antes de responder. Su respuesta me hará sentir que está buscando la respuesta. De lo contrario, es como si estuvieras externalizando tu trabajo a SO. –

+0

Disculpa, estaba planeando agregar un comentario, pero se desvió del trabajo. :) Estoy pensando que lo viola. Corrígeme si me equivoco, pero FMP dictamina un constructor privado y un constructor privado prohíbe la extensión. Además, ¿no tendría que modificarse la clase para admitir implementaciones alternativas? Estoy pensando en la situación en que una clase tiene métodos de fábrica estáticos. Tal vez este es solo un sabor de FMP? –

+0

Si es una clase secundaria, puedes sobreescribir el método o usar super() (asumiendo Java). Es mejor que no tenga métodos estáticos y tenga un único método que tome parámetros sobre cuál elegir con una declaración de cambio o leyendo en un archivo de configuración proporcionado. –

Respuesta

3

No, no viola el principio de abierto/cerrado en absoluto.

Abrir/Cerrado significa que puede modificar la forma en que funciona un sistema sin modificar el código que ya existe. Puede extender el código y usarlo de diferentes maneras, pero el código anterior todavía está intacto y no necesita volver a probarse.

El patrón Método de fábrica creará un tipo diferente de objeto en función de los parámetros especificados. El Método Factory realmente funciona bien con el principio Abierto/Cerrado si se hace correctamente. Sin embargo, si crea una nueva clase y luego desea que el Método de fábrica cree un nuevo objeto de ese tipo, deberá cambiar el Método de fábrica.

Aunque, si tuviera algún tipo de archivo de configuración o algo por el estilo que fuera leído por el Método de Fábrica, entonces no tendría que cambiar el Método de Fábrica ... solo el archivo de configuración que dictamine qué objeto será creado por el Método de Fábrica.

2

No. Desde su enlace Wikipedia:

software entidades (clases, módulos, funciones, etc.) deben estar abiertas para la extensión, pero cerrado para la modificación

reemplazando el método de fábrica es la extensión. Estás creando una nueva clase. No cambias la clase existente. Tienes que sustituir (a través de la configuración de tu contenedor IoC con suerte) la subclase del original.

5

El patrón de fábrica no es intrínsecamente un infractor de OCP.

Depende de cómo sigue el comportamiento de Complex.

Si Complex se requiere para apoyar la producción de nuevos tipos de Complex objeto y elige modificar Complex mediante la adición de nuevos fromX métodos se añaden a apoyarlos, entonces esto significa que Complex se convierte en un violador de la necesidad OCP porque Complex se volvió a abrir para la modificación:

class Complex 
{ 
    public static Complex fromCartesian(double real, double imag) { 
     return new Complex(real, imag); 
    } 

    public static Complex fromPolar(double modulus, double angle) { 
     return new Complex(modulus * cos(angle), modulus * sin(angle)); 
    } 

    //class opened for modification 
    public static Complex fromOtherMeans(String x , String y) { 
     return new Complex(x, y); 
    } 
} 

se podría empujar a este problema hacia abajo en un archivo de texto o archivo de propiedades de algún tipo con el fin de absolver a sí mismo de tener que cambiar la clase de java, pero no impide que de tener que escribir una lógica extra en esta área de la solución en ord er para admitir nuevos tipos de Complex.

Dependiendo del uso de Complex en su diseño (¿cómo son diferentes los tipos? ¿Cómo los está utilizando?), Hay algunas opciones alternativas que pueden aplicarse bien.

Uno de estos OCP alternativa amigable es la subclase Complex para proporcionar los métodos de fábrica adicionales. Una subclase es la ilustración más simple de cómo se extiende Complex pero no se modifica.

Otro OCP alternativa amigable a la alteración de Complex en este caso es el Decorator pattern. La decoración continua de Complex con la capacidad de crear nuevas variantes de Complex respeta el OCP porque Complex no se modifica, pero se amplía envolviéndola con una nueva funcionalidad.

Una tercera alternativa podría ser alterar la estructura de Complex para que su cálculo sea proporcionado por la composición. Esto le abriría la oportunidad de usar el Strategy pattern para diferenciar entre los diferentes comportamientos de Complex.

Lo que pasa con el patrón de fábrica es que ayuda al código de contexto respecto OCP. Se puede emplear una de las técnicas anteriores para permanecer en el lado derecho del OCP con su clase Factory, pero es probable que sus colegas echen un vistazo al gráfico de objetos, cuestionen la sabiduría de tener un gráfico de objetos sobre una sola fábrica. , y simplifíquelo de nuevo en una Fábrica, lo que lo regresa al primer ejemplo.

En tales casos, en lugar de intentar doblar la implementación del patrón de la fábrica de respetar los principios SOLID, considerar por qué se está usando en absoluto .

Cuestiones relacionadas