Metodo di fabbrica: il prodotto deve essere una classe diversa dal Creatore?

2

Voglio costruire tre siti in PHP. Lo sto facendo il più lentamente, meditatamente e attentamente possibile, per imparare il più possibile su cose come OOP e architettura software.

Dalle esperienze passate so già che ci sarà un momento in cui sarò lieto di avere funzionalità di logging. Probabilmente voglio avere diversi tipi di log, con cui intendo che in un file .ini , voglio essere in grado di specificare se la registrazione deve andare in un file di testo (magari un file delimitato da tabulazioni o CSV), un database tavolo, o segnali di fumo. Avrei (diciamo) una classe Logger, che definirebbe, ad esempio, un metodo AddEntry (). Per ogni tipo di registro, creo una sottoclasse che sappia come accedere al file CSV, scrivere su un database o attivare un incendio, rispettivamente.

Poiché so che vorrò avere un'istanza di una sottoclasse, ma non saprò quale sottoclasse istanziare fino al runtime, ho pensato che avrei usato il pattern Metodo di fabbrica. Tuttavia, quando guardo al suo articolo di Wikipedia sto notando che Creator e ConcreteCreator hanno un tipo diverso rispetto al Product , se sto leggendo correttamente l'UML. La mia domanda si riduce a questo:

Voglio avere il metodo factory come metodo statico della classe base di Logger stessa. Se lo faccio, mi sto preparando per una trappola che non vedo ancora? C'è una ragione per cui Creator e ConcreteCreator dovrebbero essere di un tipo diverso da Product ?

    
posta toon81 08.04.2013 - 18:57
fonte

3 risposte

5

Non deve essere, no.

Un esempio che posso pensare è in .NET Framework in System.Net.WebRequest.Create (). Restituirà un oggetto di una classe derivata da WebRequest, basato sulla parte del protocollo dell'URL che gli è stata passata.

Tuttavia, ci sono problemi con questo.

Non è possibile iniettare una fabbrica, se si tratta di un metodo statico del tipo che viene generato. (Bene, in .NET, puoi inserirlo come Func < WebRequest & gt ;, ma questo non è ancora l'ideale come iniettare un oggetto factory.)

Non è altrettanto accurato quando si arriva ad ampliare la fabbrica con la propria classe. Se esistesse una classe WebClientFactory standard, con un'interfaccia che esponeva un metodo Create, sarei in grado di racchiuderlo in una CustomWebClientFactory, utilizzando la stessa interfaccia e il codice chiamante non saprebbe mai la differenza.

Queste sono preoccupazioni abbastanza banali, ma la tua domanda è abbastanza banale. Giralo e chiediti questo: perché non dovresti usare una classe Factory per il metodo Factory?

    
risposta data 10.04.2013 - 19:28
fonte
3

Dovrebbero essere di tipi diversi perché uno è un Factory , l'altro è il tipo di oggetto che Factory produce.

Nel tuo caso puoi avere LoggerFactory e sottoclassi distinte della classe base Logger . La classe factory genererà una delle sottoclassi di Logger in base agli argomenti forniti

Vorrei tentare di chiarire: dalla pagina di wikipedia: "La creazione di un oggetto richiede spesso processi complessi non appropriati da includere all'interno di un oggetto di composizione. La creazione dell'oggetto può portare a una significativa duplicazione del codice, potrebbe richiedere informazioni non accessibili al oggetto compositivo, potrebbe non fornire un livello sufficiente di astrazione, o potrebbe non essere parte delle preoccupazioni del compositore "

In sostanza, stai usando l'oggetto factory per rimuovere un sacco dal codice bootstrap dal costruttore del tipo di oggetti che la factory creerà.

Avere la fabbrica e gli oggetti costruiti condividono la stessa classe non risolve il problema della separazione delle preoccupazioni poiché il codice sarebbe nella stessa classe.

    
risposta data 08.04.2013 - 19:05
fonte
1

Factory e Product dovrebbero essere classi diverse.

Il principio di responsabilità singola afferma che ogni classe dovrebbe avere un'unica responsabilità. Se una classe fosse responsabile sia della fabbrica di implementazione che della registrazione, ci sarebbero due responsabilità.

Altro su link

    
risposta data 11.04.2013 - 17:16
fonte

Leggi altre domande sui tag