2009-09-30 17 views
5

Devo creare una classe che sarà responsabile dell'elaborazione del set di risultati, ma potrebbe accadere che algoritmi diversi debbano essere utilizzati per elaborare quel set di risultati.Modelli di fabbrica e strategia

sono consapevole delle seguenti opzioni:

1) utilizzare la strategia di patern, sotto è pseudo codice:

interface Strategy { 
    processResultSet(ResultSet rs); 
} 

class StrategyA implements Strategy { 
    processResultSet(ResultSet rs); 
} 

class StrategyB implements Strategy { 
    processResultSet(ResultSet rs); 
} 

classe Context conterrà riferimento alla strategia e client dovrebbe passare l'attuazione della strategia di creazione Oggetto di contesto, ovvero

class Context { 
    private Strategy strategy; 

    public Context(Strategy strategy) { 
    this.strategy = strategy; 
    } 

    public doSomething(rs) { 
    strategy.processResultSet(rs); 
} 

Il problema è che non voglio passare l'oggetto strategia al contesto ma mi piacerebbe creare qualcosa li ke StrategyFactory che sarà responsabile della creazione di una concreta implementazione della strategia. Separerebbe il Cliente dalla Strategia - è un buon design?

Si tratta di un mix di strategia e fabbrica o di fatto solo modello di fabbrica?

+0

Se si separa il Cliente dall'implementazione della sua strategia, in che modo Factory (o eventualmente Factory Astratta) saprà quale Strtegy implementare quando tenta di instanciare l'oggetto? –

+0

La factory potrebbe ottenere tali informazioni non dal client, ma da qualche altra parte (configurazione, ad esempio). Senza sapere la sua esatta implementazione è impossibile dirlo. –

+0

Entrambi sono punti validi @Alcon, ma sarebbe più facile fare un suggerimento informato se avessimo tutti i dettagli. –

risposta

8

È sicuramente una combinazione di strategia e fabbrica - ma non penso che sia male. I motivi sono pensati per essere combinati e usati l'uno con l'altro.

È difficile dire senza vedere questo piano di progettazione nel contesto se questo è un buon design o uno cattivo. Con solo le informazioni che hai dato qui potrebbe andare in entrambi i modi.

Sembra che la tua testa sia nel posto giusto, ma lasciatemi solo dare una parola di avvertimento: non distenderti troppo per separare il cliente dalla tua strategia. L'ho fatto in passato e questo ha portato a un caos contorto che sarebbe stato molto più semplice se avessi solo permesso una piccola connessione tra le due parti del mio codice. La separazione è buona, ma faticare per mantenere una separazione perfetta può portare a codici errati e a tutti i tipi di problemi.

+0

Per essere più precisi. I: 1) Classe di servizio 2) La classe di servizio contiene un riferimento alla classe JDBCDAO. 3) La classe JDBCDAO contiene un metodo che esegue: ResultSet rs = ps.executeQuery(); Non voglio restituire il servizio rs ma lasciare che l'oggetto JDBCDAO lo elabori e restituisca un oggetto appropriato, quindi ho voluto creare questo Factory (che crea la strategia appropriata) come membro della classe JDBCDAO. –

0

Nello scenario che dipingi, non ci sarebbe davvero bisogno di un Contesto, che sarebbe invece sostituito dalla Fabbrica che desideri. Il modello di strategia in questo caso è solo sopra la testa e uno strato di complessità non necessario. Tutto ciò di cui hai bisogno è un'interfaccia o una classe astratta, implementazioni e una Fabbrica o Proxy per recuperare le implementazioni.

+2

Se usa un'interfaccia e implementazioni per rappresentare i diversi algoritmi di gestione, per definizione è una strategia - non è così? –

2

Abbiamo usato questo è molti diversi scenari di analisi e certamente funziona. Ho scritto un blog su questo con un esempio di codice: http://www.herrodius.com/blog/136

Il trucco che usiamo è fornire all'interfaccia della strategia un metodo "canProcess" in più che restituisce semplicemente un valore booleano se la strategia è in grado di gestire i dati. La fabbrica quindi scorre semplicemente tutte le sue strategie e chiede a ognuna se può lavorare con i dati. Se possibile, restituiamo tale strategia o eseguiamo la strategia.

0

commenti Anny legati ai miei pensieri:

1) c'è un servizio - Singleton. 2) Contiene un riferimento alla classe DAO - è anche un singleton. 3) In DAO esiste un metodo che recupera ResultSet: ResultSet rs = ps.executeQuery(); Vorrei creare una strategia appropriata all'interno di DAO per elaborare questo set di risultati. Non posso passare questa strategia nel costruttore DAO perché è specifico per la richiesta di inserimento. Passarlo nel costruttore lo renderebbe lo stesso per tutte le richieste in entrata. Così ho deciso di creare una Factory all'interno di DAO (istanza dell'oggetto DAO) e all'interno di un metodo ho intenzione di creare una strategia appropriata (basata sulla richiesta - oggetto locale) dalla fabbrica e usarla per elaborare il set di risultati.

Questa soluzione è adatta alla tua opinione?

+0

No, è sovradimensionato. Basta implementare la logica nella tua classe DAO senza fabbriche o strategie. Se si identifica un codice comune o standard durante o dopo l'implementazione, è necessario ricalcolare il codice. Ma non esitare a farlo funzionare con un semplice "se" prima. – eljenso

+0

I singleton sono famosi per rendere il codice difficile da testare. Hai considerato la testabilità? – TrueWill

0

Penso che lo schema di strategia dovrebbe andare con un modello di fabbrica. E in un modo che hai usato è assolutamente corretto. In secondo luogo, sarebbe meglio se manteneste la classe di contesto come una classe astratta in modo da poter estendere diversi contesti secondo le vostre esigenze. Il resto delle cose sembra buono ma secondo l'esempio che hai citato penso che non fosse necessario ma l'hai usato nel modo giusto.

Problemi correlati