Scegliere il giusto modello di design


32

Ho sempre riconosciuto l'importanza di utilizzare modelli di progettazione. Sono curioso di sapere come gli altri sviluppatori scelgono quello più appropriato. Usi una serie di caratteristiche (come un diagramma di flusso) per aiutarti a decidere?

Per esempio:

Se gli oggetti sono correlati, ma non vogliamo specificare una classe concreta, si consideri Abstract

Quando l'istanza è lasciata alle classi derivate, considerare Factory

È necessario accedere in sequenza agli elementi di un oggetto aggregato, provare Iterator

o qualcosa di simile?


8
pdr

Penso che l'importanza sia nella capacità di riconoscere il modello più appropriato e olistico, per essere in grado di comunicarlo alla fine ad altri sviluppatori. Se questo ha senso?
Carl Sagan,

Sono d'accordo con @pdr. Penso a ciò che devo fare e ricordare il nome del modello mi aiuta a nominare la classe in modo che anche gli altri sappiano cosa fa.
Amy Blankenship,

4
Infatti. Questo potrebbe essere semplicemente riassunto in "Come si sceglie il design giusto?". Innanzitutto, non esiste un design giusto , solo un sacco di quelli sbagliati. Oltre a ciò, viene fornito con l'esperienza di pile (scegliere quelle sbagliate).
Telastyn,

Risposte:


109

Un malinteso chiave nel mondo dei codici di oggi è che i modelli sono elementi costitutivi. Prendi un AbstractFactoryqui e un Flyweightlà e forse un Singletonlaggiù e li connetti insieme a XML e presto, hai un'applicazione funzionante.

Loro non sono.

Hmm, non era abbastanza grande.

I modelli non sono elementi costitutivi

Va meglio.

Un modello è qualcosa che usi quando scopri di avere un problema: hai bisogno di una certa flessibilità che fornisce il modello o che ti sei imbattuto quando stai creando una piccola lingua nel file di configurazione e dici "aspetta un momento, fermati, questo è il suo interprete che sto scrivendo - questo è un problema noto e risolto, usa un modello Interprete ".

Ma nota lì, che è qualcosa che scopri nel tuo codice, non qualcosa con cui inizi. I creatori di Java non hanno detto "Oh, metteremo un Flyweight in the Integer" all'inizio, ma piuttosto hanno realizzato un problema di prestazioni che potrebbe essere risolto da un flyweight .

E quindi, non esiste un "diagramma di flusso" che usi per trovare lo schema giusto. Il modello è una soluzione a un tipo specifico di problema che è stato riscontrato più volte e le sue parti chiave sono state distillate in un modello.

Iniziare con il modello è come avere una soluzione e cercare un problema. Questa è una brutta cosa: porta a un eccesso di ingegneria e, in definitiva, alla mancanza di flessibilità nel design.

Mentre scrivi il codice, quando ti rendi conto che stai scrivendo una Factory, puoi dire "ah ah! Quella è una fabbrica che sto per scrivere" e usare la tua conoscenza di conoscere il modello Factory per scrivere rapidamente il prossimo codice senza tentare di riscoprire il modello Factory. Ma non inizi con "Ho un corso qui, scriverò una fabbrica per farlo in modo che possa essere flessibile" - perché non lo farà.

Ecco un estratto da un'intervista a Erich Gamma (di Gamma, Helm, Johnson e Vissides ): Come usare i modelli di design :

Cercare di usare tutti i modelli è una cosa negativa, perché finirai con progetti sintetici, progetti speculativi che hanno flessibilità che nessuno ha bisogno. Al giorno d'oggi il software è troppo complesso. Non possiamo permetterci di speculare cos'altro dovrebbe fare. Dobbiamo davvero concentrarci su ciò di cui ha bisogno. Ecco perché mi piace il refactoring agli schemi. Le persone dovrebbero imparare che quando hanno un particolare tipo di problema o odore di codice, come la chiamano in questi giorni, possono andare alla loro casella degli strumenti dei modelli per trovare una soluzione.


Il miglior aiuto per "cosa usare, quando" è probabilmente la pagina di Wikipedia per il modello di progettazione del software - la sezione "Classificazione ed elenco" descrive la categoria in cui si trova ogni modello e cosa fa. Non c'è diagramma di flusso; la descrizione è probabilmente la migliore che troverai come frammento di "cosa usare quando".

Nota che troverai diversi schemi in diverse aree di programmazione. Il web design ha un proprio set di pattern mentre JEE (non il web design) ha un altro set di pattern. I modelli per la programmazione finanziaria sono completamente diversi da quelli per la progettazione dell'interfaccia utente dell'applicazione autonoma.

Quindi ogni tentativo di elencarli tutti è intrinsecamente incompleto. Ne trovi uno, scopri come usarlo e alla fine diventa una seconda natura e non devi pensare a come o quando usarlo mai più (fino a quando qualcuno ti chiederà di spiegarlo).


11
+1 per "soluzione alla ricerca di un problema". Conoscere gli schemi ti permetterà di saltare la loro scoperta naturale quando si scopre che devi risolvere un problema che capita loro di risolvere. Imparare su di loro probabilmente ti aiuterà a migliorare le tue capacità di programmazione e progettazione, allo stesso modo in cui legge il codice di altre persone o impara un altro linguaggio di programmazione. Ma sicuramente non dovresti cercare attivamente di "adattare i pattern" al tuo codice.
Gregreg

1
Consiglio sempre agli sviluppatori di iniziare a guardare schemi per familiarizzare prima con i principi di progettazione. Ogni modello è un esempio di alcuni dei principi del design (l'insieme di principi "SOLID" è solo un esempio).
ryscl,

2
Forse aggiungi un decoratore e una facciata che avresti un'app ;-) Detto in un altro modo, il punto dei motivi del design è quello di darci un nome, un linguaggio comune quando discutiamo di ciò che stiamo costruendo. È una scorciatoia per una pila di conoscenze di sviluppo conquistate duramente.
EBarr,

2
Leggendo tra le righe qui, i passaggi per scegliere un modello di progettazione: 1. Pensa sempre criticamente a qualsiasi codice in cui stai lavorando. 2. Riassumi il codice specifico in un problema di base 3. Il problema ha una soluzione nota (modello di progettazione )? 4. Sì, come posso applicare questa soluzione ai miei dettagli? 5. Adattare la soluzione generica al problema astratto, per creare una soluzione al problema specifico.
Chris,

@ Chris che lo riassume davvero. Inoltre, non c'è nulla di sbagliato nel scriverlo senza schemi e quindi nel refactoring del codice nel modello appropriato se il design ne ha bisogno.

18

Mi chiedo:

  1. Quale problema sto cercando di risolvere?
  2. Quale modello di progettazione software (se presente) risolve più da vicino lo stesso problema o fornisce un percorso logico per risolverlo?
  3. Ho bisogno dell'astrazione aggiuntiva (e della complessità) fornita dal modello o è un'ingegnerizzazione eccessiva per il mio problema specifico? Il problema può essere risolto in modo più semplice ed efficiente senza il modello?

Il processo di scelta di un modello software non è diverso dal processo di scelta di una struttura di dati, tranne per il fatto che nella scelta di una struttura di dati, si valuterebbero le prestazioni e le caratteristiche di memoria del problema e si sceglierebbe la struttura di dati più adatta a tali caratteristiche.


Naturalmente, questo è qualcosa che riguarda l'esperienza e l'esperto, anziché un progetto o un diagramma di flusso, e sono d'accordo con te. Ma ci deve essere un certo uso di risorse complete come un cheat sheet avanzato in cui è stato classificato, almeno nel caso dei modelli più importanti e frequenti come la fabbrica, ecc. che sarebbe meglio usare un modello. conosci una risorsa del genere là fuori su internet ?!
Pmpr,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.