2009-04-30 10 views
43

He estado usando el patrón de creación de métodos de fábrica por un tiempo. Me dijeron hace poco que esta:¿Es este patrón de creación de método de fábrica?

public static class ScheduleTypeFactory 
{ 
    public static IScheduleItem GetScheduleItem(ScheduleTypeEnum scheduleType) 
    { 
     IScheduleItem scheduleItem = null; 

     switch (scheduleType) 
     { 
      case ScheduleTypeEnum.CableOnDemandScheduleTypeID: 
       { 
        scheduleItem = new VODScheduleItem(); 
        break; 
       } 
      case ScheduleTypeEnum.BroadbandScheduleTypeID: 
       { 
        scheduleItem = new VODScheduleItem(); 
        break; 
       } 
      case ScheduleTypeEnum.LinearCableScheduleTypeID: 
       { 
        scheduleItem = new LinearScheduleItem(); 
        break; 
       } 
      case ScheduleTypeEnum.MobileLinearScheduleTypeID: 
       { 
        scheduleItem = new LinearScheduleItem(); 
        break; 
       } 
     } 

     return scheduleItem; 
    } 
} 

no es un patrón de creación método de fábrica por mi ejemplo "Tech" sin decirme por qué o darme su interpretación. Le pedí amablemente una explicación y ella me dijo que no tenía tiempo. Me dijeron que simplemente cambie el nombre. Si estoy equivocado, sin duda aceptaré que lo he implementado de forma incorrecta durante años. ¿Es así como USTED implementaría el patrón de creación de métodos de fábrica? Gracias por adelantado.

+3

Es una fábrica, aunque muy sencilla. Por lo general, la fábrica se usa para encapsular lógica de decisión compleja y, en su caso, la lógica de decisión es simplemente búsqueda enum. –

+4

el patrón de fábrica es ocultar la complejidad. buscar una enumeración es simple, pero cuando lo hago una vez, en lugar de 10 veces el cliente, lo preferiría. pero comenzaría a refactorizar el método. hay muchas líneas que se pueden eliminar – cRichter

+0

Es un método de fábrica estático. Consulte: http://stackoverflow.com/questions/929021/what-are-static-factory-methods –

Respuesta

30

Claro que me parece el patrón de fábrica. No veo nada malo con su implementación.

De Factory method pattern:.

La esencia del patrón de fábrica es a "Definir una interfaz para crear un objeto, sino dejar que las subclases deciden qué clase de ejecutar el método de fábrica permite una clase aplazar creación de instancias a subclases ".

Esto es exactamente lo que estás haciendo.

Como nota al margen: una buena regla general es que cada vez que alguien le dice algo y no puede o no quiere proporcionar una justificación para su declaración, hay una buena probabilidad de que no estén calificados para hacer la declaración.

+10

"cada vez que alguien le dice algo y no puede o no quiere proporcionar una justificación para su declaración, existe una buena posibilidad no están calificados para hacer la declaración "QFT – annakata

+1

¿Exactamente qué está haciendo? No veo que las subclases decidan aquí, solo devuelven las subclases. – Peter

+0

Quizás nos falta el punto aquí, pero tampoco veo una interfaz subclase. –

14

Sí, este es un patrón de fábrica. Mi único comentario sería que fallas silenciosamente en los valores enum que no manejas específicamente. Que se puede esperar, pero me gustaría añadir lo siguiente al final de afirmaciones como que

default: 
    throw new InvalidOperationException("Invalid Enum Value"); 
+0

¿Qué hay de malo en devolver nulo? –

+0

Lo recomiendo mucho, ya que lo hace mucho más claro cuando se extiende un sistema existente y se pierde algo. – JoshBerke

+1

+1 Para InvalidOperationException - C# es muy indulgente con los valores de enum y sería bueno saber si alguien pasó un molde de valor no válido como ese tipo de enumeración. –

5

Parece una fábrica (básica) a mí ... en muchas fábricas de la aplicación es más compleja (tal vez la participación tipos resueltos en tiempo de ejecución), pero eso no es (AFAIK) un requisito. La única otra crítica que habría agregado es combinar las cajas y hacer algo más espectacular si no se reconoce el tipo ...

0

Sí, ese es el patrón de fábrica correcto. Tu ventaja técnica es incorrecta.

2

De hecho, es una "fábrica" ​​en la que tiene un método que devuelve una instancia específica de IScheduleItem basada en algún tipo de lógica; sin embargo, probablemente no sea la mejor implementación o la más fácil de mantener, dado que está utilizando una instrucción switch.

+0

¿Por qué crees que no se puede mantener porque está usando una declaración de cambio? Eso me parece perfectamente mantenible. –

+0

http://en.wikipedia.org/wiki/Factory_method_pattern muestra una declaración de cambio en un ejemplo. Me parece bien. –

+0

Un interruptor está bien en casos simples en casos más complejos puede ser difícil de mantener; sin embargo, hasta que tengas los casos complejos, me quedaría con lo simple. – JoshBerke

4

Bueno, Wikipedia dice it is un método de fábrica:

public class ImageReaderFactory 
{ 
    public static ImageReader getImageReader(InputStream is) 
    { 
     int imageType = figureOutImageType(is); 

     switch(imageType) 
     { 
      case ImageReaderFactory.GIF: 
       return new GifReader(is); 
      case ImageReaderFactory.JPEG: 
       return new JpegReader(is); 
      // etc. 
     } 
    } 
} 
0

Parece un patrón básico de fábrica para mí. Tengo curiosidad por saber por qué su líder tecnológico no cree que esto sea un patrón.

También estoy decepcionado de que ella no se tome el tiempo para explicar las cosas. Habiendo sido un líder tecnológico antes en un equipo, es curioso tomarse el tiempo para explicar sus decisiones.

+3

La respuesta básica sería: su líder tecnológico es un idiota que está hablando por el culo. – TheTXI

+0

TheTXI: Gracias por decir lo que estaba pensando :-) – JoshBerke

+0

De acuerdo con Josh. +1 –

8

creo que se llama tradicionalmente el patrón de la fábrica sencilla para distinguirla de la 'verdadera' Abstract Factory patrón. Puede ser que no estés siguiendo un tipo de práctica de denominación interna. Sin embargo, ella realmente debería explicarse.

0

Lo que el líder tecnológico probablemente piense es que el patrón Factory es reemplazar un constructor en el mismo objeto, no devolver subclases, o tal vez solo devolver subclases de una superclase, no de un objeto no relacionado. Está mal, pero ese es probablemente el pensamiento.

El hecho de que Wikipedia liste su patrón como ejemplo muestra que es correctamente un patrón de fábrica. Los patrones se definieron para proporcionar un lenguaje común para soluciones comunes, por lo que claramente si Wikipedia muestra esto como un ejemplo, es parte del lenguaje común. Un debate académico sobre lo que el "Patrón de Fábrica" ​​es en cierto sentido abstracto pierde el sentido de los patrones.

+0

mmm, Head First se refiere a mucho, y especialmente en ninguno de los debates académicos. – Peter

4

Ese es el patrón de fábrica, pero no es necesariamente la variante más fácil de mantener. Una variante más fácil de mantener mantendría algún tipo de mapa global entre los valores ScheduleTypeEnum y los subtipos de concreto reales de IScheduleItem - de esa manera, podría reemplazar la declaración switch con una búsqueda del mapa.

¿Por qué es más fácil de mantener? Debido a que los autores de subclases pueden agregar pares al mapa en el sitio donde derivan la clase, en lugar de en la función de fábrica GetScheduleItem(). Por lo tanto, este último nunca necesita actualización; está constantemente actualizado.

En C++ puede hacer esto usando un std::map global: para cada subclase concreta, el autor de la subclase agrega una variable global ficticia que en realidad solo registra la clase (añadiendo al mapa) en su constructor, que ejecuta en el momento del inicio del programa. Estoy seguro de que hay una manera conveniente de hacer lo mismo en C#.

(C++ gurú Herb Sutter tiene un entertaining description here, pero es bastante C++ -. Pesada)

0

recuperar el poder en este momento! Simplemente suelte 'Tipo' de la fraseología. ScheduleFactory FTW. Espera, ¿es esta una fábrica para 'Horarios' o 'Horario'? Si se trata de un cronograma, la fábrica debe llamarse 'ScheduleItemFactory'. Se expresivo !!!

4

Parece un patrón de fábrica para mí. Dile a tu líder tecnológico que no tienes tiempo para explicar por qué está equivocada.

-1

Eso es un libro de texto Factory Pattern.

Algunos textos lo llaman Fábrica simple Patteren, pero nunca he visto ningún criterio para lo que significa "Simple".

En mi práctica, un patrón de fábrica es cualquier creación inteligente de una clase concreta que corresponda a una interfaz deseada.

Pero, ¿por qué luchar contra su liderazgo tecnológico por nombrar un método? Renombrarlo, seguir con tu vida.

+1

¿Libro de texto? ¿Qué libro? No GoF o la cabeza primero seguro. – Peter

5

Me sorprende que muchos dicen que este es el patrón de fábrica. (Así que es probable que esté pensando en esto, así que avíseme.)

Me parece que lo que tienes allí es solo una parte del diseño. Si lo llama desde su cliente, se lo conoce como una fábrica "simple", pero en realidad no se considera un patrón de diseño. (No me malinterpreten, lo hago todo el tiempo).

El patrón de diseño de fábrica indicaría que su fábrica hereda/implementa una interfaz abstracta de fábrica/fábrica.

Luego, en su clase que necesita usar la fábrica (el cliente), establece el tipo de fábrica en el resumen/interfaz, creando una fábrica de concreto: es decir -> Fábrica IFactory = new ConcreteFactory() ;

La fábrica de concreto crearía entonces su IScheduleItem (dejándolo en fábrica para crear realmente el tipo concreto).

Al final, creo que todo se trata de un acoplamiento flojo. Mientras que una fábrica "simple" combina holgadamente la construcción del producto del cliente, no desacopla la fábrica. El patrón de fábrica también desacopla la fábrica.

Por otra parte, es temprano, no he tomado café, y tengo la desagradable costumbre de publicar respuestas absolutamente horribles que omiten todo el tema de la pregunta.

+0

Creo que es el patrón Abstract Factory – willcodejavaforfood

+0

http://en.wikipedia.org/wiki/Abstract_factory_pattern – user24985

+0

No, eso no es un patrón Abstract Factory, corey describe Factory Method Pattern, y lo hace bastante correctamente. Abstract Factory es otra capa de abstracción que * podría * utilizar el patrón Factory Method para crear fábricas. –

0

La explicación más simple del patrón de fábrica, que aprendí de una clase de patrones y prácticas, fue que si confía en otra clase para crear las instancias de su clase, entonces está usando el patrón de fábrica.

Por supuesto, muchas veces desea agregar una capa de indirección haciendo que su clase sea abstracta o una interfaz.

Esta es una vista muy simplificada, pero de cualquier forma, está utilizando el patrón de fábrica.

31

Estoy de acuerdo en llamar al método un "Método de fábrica", aunque el diseño no es estrictamente un "Patrón de método de fábrica".
Aquí es un punto clave (de Wikipedia):

... El método de fábrica permite una ejemplificación aplazar la clase de subclases "

Dado que la clase es estática y método estático (por lo tanto no. -virtual), no hay un "aplazamiento" posible.

conceptualmente, aviso también, que esta implementación, aunque proporciona la encapsulación, no desacoplar/retrasar cualquier decisión.

Hav Dicho esto, el mismo artículo de Wikipedia presenta este esquema como una variante del "Patrón de método de fábrica".

Resumen del Resumen: En mi opinión este fragmento no es una adecuada aplicación del "Método de fábrica OO patrón de diseño", ya que no satisface "una ejemplificación aplazar la clase a las subclases." Sin embargo, personalmente me referiría libremente a esta solución como "método de fábrica".

Para que sea real patrón de método de fábrica, debe permitir que el método sea anulado por subclases. Es decir. La clase de fábrica (ScheduleTypeFactory) debe ser extensible (es decir, no estática) y GetScheduleItem debe ser virtual.

+2

¿Por qué las respuestas correctas obtienen tan pocos votos? – Peter

+0

Muy buena respuesta (señala la diferencia por Método de Fábrica y Patrón de Método de Fábrica), y de hecho la más exhaustivamente correcta (ya que proporciona la ruta para convertir este diseño en el de GoF). –

+0

Esta es una gran respuesta. He estado leyendo [Patrones de diseño de Head First] (http: //www.amazon.com/First-Design-Patterns-Elisabeth-Freeman/dp/0596007124) y define una "Fábrica simple" que es más similar a lo que el OP ha presentado, pero está claro que la implementación "adecuada" del método de método de fábrica requiere un método de fábrica abstracto para ser reemplazado por subclases. Sin embargo, tengo problemas para comprender cómo el uso de subclases favorece la composición por sobre la herencia. –

12

Su fragmento de código es lo que en Head First Design Patterns se llama "The Simple Factory" (p.117).
La principal diferencia con el Factory Method Pattern es ConcreteCreator (compare el diagrama en la esquina superior derecha), que es una clase simple en su caso.
En el "patrón real", la clase de fábrica es abstracta con una clase abstracta de fábrica. Entonces, hay un nivel de abstracción más. Sin embargo, para muchos casos de uso, su Fábrica simple es suficiente.

simple de la fábrica Simple Factory http://yuml.me/7221a4c9 Método de fábrica del patrón Factory Method Pattern http://yuml.me/3d22eb4e

+0

¿Qué herramienta usaste para generar estos diagramas? Me gusta el aspecto y la sensación incompletos. –

+9

Eso es yUML: http://yuml.me Es increíble, genera UML por texto (por ejemplo, [Cliente] +1 -> * [Pedido]) y el resultado se representa como una imagen o PDF con un simple enlace así: http://yuml.me/5f1fa3ba que puedes incluir en cualquier contenido, ej. Ice09

8

Su ventaja es correcto (lo siento por el formato, pero esta respuesta necesitan algo de él con el fin de ser visto entre la línea principal que está indicando la el plomo es un idiota): ni en el libro de GOF ni en Head First se trata de un método de fábrica.

GoF:

“Definir una interfaz para crear un objeto , ¡pero las subclases deciden qué clase instanciar. Fábrica método permite que una clase diferir de instancias a las subclases.”

En su ejemplo, es no una subclase que está decidiendo.

¿Lo ha implementado incorrectamente todos estos años? No, simplemente no ha implementado el patrón de fábrica, pero lo que a veces se conoce como el 'Patrón de Fábrica Simple', que probablemente ha hecho bien el trabajo.

0

Su tecnología está justo en el cambio de nombre del método:

public static IScheduleItem GetScheduleItem(ScheduleTypeEnum scheduleType) 

La acción del método no es para conseguir algo, es crear algo. ¿Cómo se decide qué scheduleType se debe crear? Parece que la lógica debería ser encapsulada no el interruptor del tipo.

¿Por qué también el estático en la clase? ¿De dónde lo estás usando?

public class ScheduleTypeFactory 
{ 
    public static IScheduleItem createScheduleFrom(ScheduleTypeEnum scheduleType) 
    { 

     switch (scheduleType) 
     { 
      case ScheduleTypeEnum.CableOnDemandScheduleTypeID: 
      case ScheduleTypeEnum.BroadbandScheduleTypeID: 
       return new VODScheduleItem(); 
      case ScheduleTypeEnum.LinearCableScheduleTypeID: 
      case ScheduleTypeEnum.MobileLinearScheduleTypeID: 
        return new LinearScheduleItem(); 
     } 

     raise InvalidSchedule; 
    } 
} 
Cuestiones relacionadas