È possibile utilizzare una singola Factory per creare scopi simili, ma diversi negli oggetti di messa a fuoco?

2

Sono preoccupato che utilizzi o meno FactoryMethod correttamente.

Sfondo:

Sto rifattando il codice legacy e ho identificato un pattern: esiste un God Object che viene creato in memoria e in seguito varie parti di esso vengono salvate in molte tabelle diverse. Ad esempio, varie parti sono chiamate Selection , Design , Plot .

Cosa ho fatto

Ho creato un SelectionPersisterFactory che restituisce un oggetto SelectionPersister , che è responsabile del salvataggio di Selection nel database.

Il prossimo passo sarebbe creare DesignPersisterFactory che restituisca DesignPersister , che salva Design nel database.

Ma poi mi sono fermato e chiedo:

Domanda

Posso creare un singolo PersisterFactory e avere che restituisce SelectionPersister , DesignPersister , PlotPersister , ecc.? da una singola fabbrica?

Pro / Con

  • "Il Pro" sarà che tutti usano lo stesso repository e Posso inizializzare quel repository una volta, invece di farlo per ogni nuovo tipo di Persister

  • "La Con" è che mi occuperò della creazione della fabbrica diversi tipi di Persisters, ma non sono sicuro che sia un necessariamente una brutta cosa Ad esempio, non sono sicuro se romperò SRP.

Per chiarire il mio titolo, "scopo simile" - gli oggetti sono pensati per mantenere qualcosa, "diversi a fuoco" - gli oggetti persistenti si focalizzano su parti diverse di God oggetto.

Obiettivo / Caso di utilizzo

La situazione attuale è che ho l'oggetto God contenente tutto ciò che è stato generato durante "l'attività del cliente". Quell'oggetto è un oggetto in memoria. Inoltre, permea molto del codebase ed è poco pratico cambiare in un momento. Non è sempre ben separato nei suoi sottocomponenti distinti, sebbene ci provi.

L'attività in corso è "Salva questa sessione dell'attività del cliente (ovvero l'oggetto dio) nel database". Ciò include il salvataggio:

  • Elementi selezionati dall'utente alla tabella items
  • Stampa generata dagli elementi precedenti nella tabella plot
  • Progetta i dati degli oggetti da sopra, nella tabella design
  • e così via (solo 1-2 altri)

Why you think you need all these different persisters?

Le diverse parti attingono da diverse sezioni dell'oggetto dio. Originariamente era tutto un codice procedurale che faceva solo istruzioni SQL facendo tutto il salvataggio del DB sopra, coprendo oltre 500 linee. Volevo suddividerlo in pezzi più maneggevoli e mi è venuta un'idea "Separiamo le diverse parti dell'oggetto divino in metodi separati". Dal momento che vengono mantenuti nel database, perché non chiamarli Persisters .

it would be worth to know if you have only a small fixed number of parts class

Sì, ho un numero fisso di classi di parti, diciamo 5 o 6. Diverse "attività del cliente" generano esigenze leggermente diverse. Quindi alcune sessioni potrebbero avere la necessità di mantenere 1 o 2 parti, alcune potrebbero aver bisogno di tutto 5. Non prevedo la necessità di aggiungere più classi di parti, ma piuttosto di mantenere il codice semplice.

    
posta Dennis 21.06.2016 - 17:44
fonte

2 risposte

2

Se hai un piccolo numero fisso di tipi di parti diversi che saranno raramente estesi, puoi mantenerlo pragmatico e dare al tuo PersisterFactory una manciata di metodi diversi come CreateDesignPersister , CreatePlotPersister o CreateSelectionPersister . Se ognuna di queste classi contiene solo un singolo metodo di persistenza, anche quello forse di overengineering, un generico "Persister" con tre metodi Save(Design d) , Save(Selection s) , SavePlot(Plot p) potrebbe andare bene.

Tuttavia, se la tua situazione ha un aspetto diverso e hai molti tipi di parti differenti e vuoi che l'elenco sia facilmente estendibile, potresti prendere in considerazione la possibilità di passare a un design più sofisticato. Innanzitutto, considera se hai davvero bisogno di una logica "Persister" diversa per ogni tipo di parte, o se la parte persistente non può essere implementata in un modo più generico, con una classe di GenericPersister che usa il reflection (si presume che tu usi un linguaggio di programmazione che supporta questo) per mantenere tutto ciò che si passa ad esso.

Se ciò non è possibile o non vale lo sforzo di generalizzazione, la prossima cosa che puoi provare è avere una classe Persister che usi il modello di strategia, fornendo DesignPersisterStrategy , SelectionPersisterStrategy e così via. Ci sarà un solo oggetto Persister , contenente l'unico riferimento al tuo repository (o qualsiasi altra risorsa tu voglia riutilizzare). Fornirà anche un metodo pubblico Save che sceglierà la strategia corretta in base al tipo di oggetto passato e quindi lo userà per salvare correttamente l'oggetto. Quindi riduci il numero di classi necessarie da "3 * N" a "2 * N + 1" (dove N è il numero di tipi di parti), senza violare l'SRP e comunque condividere risorse comuni.

    
risposta data 21.06.2016 - 21:49
fonte
1

Quello che stai decifrando è un modello di progettazione comune e, come ha commentato @Robert, il suo nome è fabbrica astratta ricorda che SRP significa che un'entità deve avere solo un motivo per cambiare non che debba fare solo una cosa, o restituire solo un tipo di risultato. Quindi no, non stai violando SRP.

    
risposta data 21.06.2016 - 20:32
fonte