2009-04-30 14 views
43

Ho usato il modello di creazione del metodo di fabbrica per un po 'di tempo. Mi è stato recentemente detto che questo:Questo modello di creazione del metodo di fabbrica è?

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; 
    } 
} 

non è un modello di creazione metodo factory per il mio vantaggio "Tech" senza dirmi perché o mi dà la sua interpretazione. Ho gentilmente chiesto una spiegazione e lei mi ha detto che non aveva tempo. Mi è stato detto di ribattezzarlo. Se sbaglio, allora accetterò senza dubbio di averlo implementato in modo errato per anni. È così che TU implementeresti il ​​modello di creazione del metodo di produzione? Grazie in anticipo.

+3

Si tratta di una fabbrica anche se molto semplice. Di solito la fabbrica viene utilizzata per incapsulare la logica decisionale complessa e nel tuo caso la logica decisionale è semplicemente la ricerca di enum. –

+4

il modello di fabbrica serve a nascondere la complessità. cercare un enum è semplice, ma quando lo faccio una volta, invece di 10 volte il client, preferirei. ma vorrei iniziare a rifattorizzare il metodo. ci sono molte linee che possono essere cancellate. – cRichter

+0

È un metodo di fabbrica statico. Fare riferimento a: http://stackoverflow.com/questions/929021/what-are-static-factory-methods –

risposta

30

Certo sembra il modello di fabbrica per me. Non vedo nulla di sbagliato nella tua implementazione.

Da Factory method pattern:.

L'essenza del modello di fabbrica è a "Definire un'interfaccia per la creazione un oggetto, ma lasciare che le sottoclassi decidere quale classe istanziare Il metodo di fabbrica consente una classe posticipare l'istanziazione alle sottoclassi. "

Questo è esattamente quello che stai facendo.

Come nota a margine: una buona regola empirica è che ogni volta che qualcuno ti dice qualcosa e non è in grado o non è disposto a fornire una motivazione per la loro dichiarazione, c'è una buona probabilità che non siano affatto qualificati per fare la dichiarazione.

+10

"ogni volta che qualcuno ti dice qualcosa e non è in grado o non vuole fornire una motivazione logica per la sua dichiarazione, ci sono buone possibilità non sono qualificati per rendere la dichiarazione affatto "QFT – annakata

+1

Esattamente quello che sta facendo? Non vedo nessuna sottoclasse decidere qui, solo sottoclassi restituite. – Peter

+0

Forse ci manca il punto qui, ma non vedo nemmeno un'interfaccia sottoclasse. –

14

Sì, questo è un modello di fabbrica. Il mio unico commento sarebbe che si fallisce silenziosamente per i valori enum che non si gestiscono specificamente. Che può essere previsto, ma mi piace aggiungere quanto segue al fine di dichiarazioni come queste

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

Cosa c'è di sbagliato nel restituire null? –

+0

Lo consiglio vivamente in quanto rende molto più chiaro quando estendi un sistema esistente e perdi qualcosa. – JoshBerke

+1

+1 per InvalidOperationException - C# è molto indulgente nei confronti dei valori enumerati e sarebbe utile sapere se qualcuno ha trasmesso un cast di valori non validi come quel tipo di enum. –

5

Sembra una fabbrica (base) a me ... in molte fabbriche l'implementazione è più complessa (forse che coinvolge tipi risolti in fase di esecuzione), ma ciò non è (AFAIK) un requisito. L'unica altra critica che avrei aggiunto è di combinare i casi e fare qualcosa di più drammatico se non si riconosce il tipo ...

0

Sì, questo è il modello di fabbrica va bene. La tua guida tecnica è sbagliata.

2

È effettivamente una "fabbrica" ​​in quanto si dispone di un metodo che restituisce un'istanza specifica di IScheduleItem basata su una sorta di logica; tuttavia, probabilmente non è la migliore implementazione o la più gestibile dato che si sta utilizzando un'istruzione switch.

+0

Perché pensi che non sia gestibile perché sta usando un'istruzione switch? Mi sembra perfettamente gestibile. –

+0

http://en.wikipedia.org/wiki/Factory_method_pattern mostra un'istruzione switch in un esempio. Sembra bene per me. –

+0

Un passaggio va bene in casi semplici in casi più complessi che potrebbero diventare difficili da mantenere; comunque, finché non avrai i casi complessi rimarrò semplice. – JoshBerke

4

Bene, Wikipedia dice it is un metodo factory:

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

Sembra uno schema di base fabbrica per me. Sono curioso di sapere perché il tuo capo tecnico non pensa che questo sia un modello.

Sono anche deluso che non si prenda il tempo di spiegare le cose. Essendo stato un leader tecnologico in una squadra, è necessario dedicare del tempo a spiegare le proprie decisioni.

+3

La risposta di base sarebbe: il suo capo tecnico è un idiota che sta parlando dal suo culo. – TheTXI

+0

TheTXI: Grazie per aver detto cosa stavo pensando :-) – JoshBerke

+0

Concordato con Josh. +1 –

8

penso che è tradizionalmente chiamato il semplice modello di fabbrica per distinguerlo dal 'reale' Abstract Factory modello. Potrebbe essere che non stai aderendo a una sorta di pratica di denominazione interna. Dovrebbe davvero spiegarsi.

0

Ciò che il leader della tecnologia probabilmente pensa è che il modello Factory sostituisce un costruttore nello stesso oggetto, non restituisce sottoclassi, o forse restituisce solo sottoclassi da una superclasse, non da un oggetto non correlato. È sbagliato, ma probabilmente è questo il pensiero.

Il fatto che Wikipedia elenchi il modello come esempio mostra che è correttamente un modello di fabbrica. I pattern sono stati definiti per fornire un linguaggio comune per soluzioni comuni, quindi, se Wikipedia mostra questo come esempio, fa parte del linguaggio comune. Un dibattito accademico su ciò che il "Modello di fabbrica" ​​è in qualche senso astratto manca il punto di schemi.

+0

mmm, Head First si riferisce a molto, e soprattutto in nessun dibattito accademico. – Peter

4

Questo è il modello di fabbrica, ma non è necessariamente la variante più mantenibile. Una variante più manutenibile manterrebbe una sorta di mappa globale tra i valori ScheduleTypeEnum ei sottotipi di calcestruzzo effettivi di IScheduleItem - in questo modo, è possibile sostituire l'istruzione switch con una ricerca della mappa.

Perché è più gestibile? Poiché gli autori di sottoclassi possono aggiungere coppie alla mappa nel sito in cui derivano la classe, anziché nella funzione di fabbrica GetScheduleItem(). Quindi, quest'ultimo non ha mai bisogno di aggiornamento; è costantemente aggiornato.

In C++ è possibile farlo utilizzando un globale std::map - per ogni sottoclasse concreta, l'autore della sottoclasse aggiunge una variabile globale fittizia che in realtà solo registra la classe (con l'aggiunta alla mappa) nel suo costruttore, che corre all'avvio del programma. Sono certo che c'è un modo conveniente per fare la stessa cosa in C#.

(C++ guru Herb Sutter ha un entertaining description here, ma è abbastanza C++ -. Pesante)

0

riprendere il potere in questo momento! Basta rilasciare "Tipo" dal testo. ScheduleFactory FTW. Aspetta, questa è una fabbrica per "Schedules" o "ScheduleItems"? Se si tratta di scheduleitems, la factory dovrebbe essere chiamata 'ScheduleItemFactory'. Sii espressivo !!!

4

Sembra un modello di fabbrica per me. Dì al tuo capo tecnico che non hai tempo di spiegare perché ha torto.

-1

Questo è un modello di fabbrica da manuale.

Alcuni testi lo chiamano Simple Factory Patteren, ma non ho mai visto alcun criterio per ciò che significa "Semplice".

Nella mia pratica, un modello di fabbrica è una creazione intelligente di una classe concreta corrispondente all'interfaccia desiderata.

Ma perché combattere il tuo vantaggio tecnico sulla denominazione di un metodo. Rinominalo, vai avanti con la tua vita.

+1

Libro di testo? Che libro di? Non GoF o testa di sicuro. – Peter

5

Sono sorpreso che molti affermino che questo è il modello di fabbrica. (Quindi è probabile che sto pensando a questo sbagliato, quindi per favore fatemelo sapere.)

Mi sembra che quello che hai sia solo una parte del design. Se la chiami dal tuo cliente, viene definita "fabbrica semplice", ma non è realmente considerata un modello di progettazione. (Non fraintendermi, lo faccio sempre).

Lo schema di progettazione di fabbrica indica che la fabbrica eredita/implementa un'interfaccia fabbrica/fabbrica astratta.

Quindi, nella classe che deve utilizzare la fabbrica (il client), si imposta il tipo di fabbrica sull'estratto/interfaccia, creando una fabbrica di cemento: ie -> Fabbrica IFactory = nuova ConcreteFactory() ;

La fabbrica di cemento creerà quindi il tuo IScheduleItem (lasciandolo alla fabbrica per creare effettivamente il tipo di calcestruzzo).

Alla fine penso che il punto sia l'accoppiamento libero. Mentre una fabbrica "semplice" accoppia liberamente la costruzione del prodotto dal cliente, non disaccoppia la fabbrica. Il modello di fabbrica disaccoppia anche la fabbrica.

Poi di nuovo, è presto, non ho preso il caffè, e ho la cattiva abitudine di postare risposte assolutamente orribili che mancano l'intero punto della domanda.

+0

ho beleive che è il modello Abstract Factory – willcodejavaforfood

+0

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

+0

No, questo non è un motivo Abstract Factory, Corey descrive Factory Method modello, e lo fa molto correttamente. Abstract Factory è ancora un altro livello di astrazione, che * potrebbe * utilizzare il pattern Metodo di fabbrica per creare fabbriche. –

0

La spiegazione più semplice del modello di fabbrica, che ho imparato da un modello e una lezione di pratica, era che se ci si affida a un'altra classe per creare le istanze della classe, si utilizza il modello di fabbrica.

Naturalmente, spesso si desidera aggiungere uno strato di riferimento indiretto rendendo la classe astratta o un'interfaccia.

Questa è una visualizzazione molto semplificata, ma in entrambi i casi, si sta utilizzando il modello di fabbrica.

31

Accetto di chiamare il metodo "Metodo di fabbrica", sebbene il progetto non sia strettamente un "Modello di metodo di fabbrica".
Qui è un punto chiave (da Wikipedia):

... Il metodo di fabbrica consente un'istanza di classe rinviare alle sottoclassi "

Dal momento che la classe è statico e metodo statico (quindi non. -Virtual), non v'è alcuna "rinviare" possibile.

Concettualmente, avviso anche, che questa implementazione, anche se fornisce l'incapsulamento, non scindere/ritardare qualsiasi decisione.

Hav detto questo, lo stesso articolo di Wikipedia presenta questo schema come una variante del "Modello metodo di fabbrica".

Sintesi della sintesi: "un'istanza di classe rinviare alle sottoclassi" Secondo me questo frammento non è una vera e propria applicazionedella "Factory Method OO Design Pattern", dal momento che non soddisfa Però personalmente, mi riferirei liberamente a questa soluzione come "metodo di fabbrica".

Per renderlo reale modello metodo di fabbrica, è necessario consentire il metodo per essere sostituito da sottoclassi. Cioè factory class (ScheduleTypeFactory) deve essere estensibile (ovvero non statico) e GetScheduleItem deve essere virtuale.

+2

Perché le risposte giuste ottengono così pochi voti? – Peter

+0

Risposta molto buona (individua la differenza tra il metodo di fabbrica e il modello di metodo di fabbrica), e in realtà quello esaurientemente corretto (poiché fornisce il percorso per trasformare questo disegno in quello di GoF). –

+0

Questa è un'ottima risposta. Ho letto [Head First Design Patterns] (http: //www.amazon.com/First-Design-Patterns-Elisabeth-Freeman/dp/0596007124) e definisce una "Fabbrica Semplice" che è più simile a ciò che l'OP ha presentato, ma è chiaro che l'implementazione "corretta" del metodo metodo di fabbrica richiede un metodo factory astratto per essere sovrascritto dalle sottoclassi. Ho difficoltà a capire, tuttavia, come l'utilizzo di sottoclassi favorisca la composizione sull'ereditarietà. –

12

Il frammento di codice è ciò che in Head First Design Patterns è chiamato "La fabbrica semplice" (p.
La differenza principale con lo è ConcreteCreator (confronta il diagramma nell'angolo in alto a destra), che è una classe semplice nel tuo caso.
Nel "modello reale" la classe factory è astratta con una classe factory astratta. Quindi, c'è un altro livello di astrazione. Tuttavia, per molti casi d'uso, è sufficiente la tua Simple Factory.

semplice fabbrica Simple Factory http://yuml.me/7221a4c9 Factory Method modello Factory Method Pattern http://yuml.me/3d22eb4e

+0

Quale strumento hai usato per generare questi diagrammi? Mi piace l'aspetto e l'imprecisione. –

+9

Questo è yUML: http://yuml.me È semplicemente fantastico, si genera UML per testo (ad esempio [Cliente] +1 -> * [Ordine]) e il risultato viene visualizzato come immagine o PDF con un semplice collegamento in questo modo: http://yuml.me/5f1fa3ba che puoi includere in qualsiasi contenuto, ad es. Ice09

8

Il vostro vantaggio è giusto (scusate per la formattazione, ma questa risposta hanno bisogno di alcuni di essi, al fine di essere visto tra la linea principale che è l'indicazione della piombo è un idiota): né dal libro del GOF né da Capo prima questo è un metodo di fabbrica.

GoF:

“Definire un'interfaccia per la creazione di un oggetto , ma lasciare che le sottoclassi decidere quale classe istanziare. Fabbrica metodo consente una classe di rinviare instanziazione alle sottoclassi.”

Nel tuo esempio, non è una sottoclasse che sta decidendo.

Avete implementato in modo errato in tutti questi anni? No, non hai appena implementato il modello di fabbrica, ma quello che a volte viene definito "modello di fabbrica semplice", che probabilmente ha svolto bene il lavoro.

0

tuo Tech è proprio sul rinominare il metodo:

public static IScheduleItem GetScheduleItem(ScheduleTypeEnum scheduleType) 

L'azione del metodo non è quello di ottenere qualcosa, è quello di creare qualcosa. Come si decide quale scheduleType deve essere creato? Sembra che la logica dovrebbe essere incapsulata non lo switch del tipo.

Anche perché il statico sulla classe? Da dove lo stai 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; 
    } 
} 
Problemi correlati