Design orientato agli oggetti: cosa fare quando la responsabilità della classe è grande

3

Ho applicato i principi del GRASP e ho finito per avere una classe chiamata Ambiente. Le responsabilità di questa classe sono:

  • Mantieni informazioni sui servizi nell'ambiente, ad es. definizione dell'ambiente (il servizio è un'altra classe)
  • Avvia / interrompi servizi che soddisfano alcuni criteri
  • Applica modifiche di configurazione a diversi servizi e mantieni l'elenco dei servizi aggiornati
  • Riavvia i servizi con la modifica della configurazione
  • Ripristina le modifiche alla configurazione alla fine della sessione
  • Cerca / Fornisci una classe di servizio in base a criteri (nome ecc.)

Secondo OOD, questo non è un problema: la responsabilità molto coesa è assegnata a questa classe .
Ma d'altra parte è un problema poiché la classe è troppo grande , anche se ha senso ogni responsabilità assegnata ad essa. Se voglio dividere questa responsabilità tra classi separate, tutte queste classi devono conoscere la "definizione dell'ambiente", che rende l'aggancio peggiore e quelle classi avranno "l'invidia caratteristica" .

Quali modelli di design sono applicabili a tale situazione? O quali altri principi possono essere applicati per avere classi coesive, meno accoppiate?

Grazie in anticipo.

    
posta Azho KG 16.08.2012 - 02:59
fonte

3 risposte

6

Probabilmente intendevi avere Environment come facciata (modello di facciata) e non implementare ogni dettaglio in esso.

Rompere tutte le funzionalità in altre classi. Imho ognuna delle responsabilità seguenti deve essere gestita da una classe separata che la classe Environment utilizza internamente.

  1. Tieni informazioni sui servizi nell'ambiente, ad es. definizione dell'ambiente (il servizio è un'altra classe)
  2. Avvia / interrompi servizi che soddisfano alcuni criteri
  3. Applica modifiche di configurazione a diversi servizi e mantieni l'elenco dei servizi aggiornati
  4. Riavvia i servizi con la modifica della configurazione
  5. Ripristina le modifiche alla configurazione alla fine della sessione
  6. Cerca / Fornisci una classe di servizio in base a criteri (nome ecc.)

Questi dovrebbero darti sei nuove classi. Probabilmente porterà anche ad altre classi in modo tale che tu possa ad esempio gestire la configurazione da classi diverse.

    
risposta data 16.08.2012 - 15:34
fonte
2

Non sono sicuro di quale sia il modello di progettazione (se presente), ma in questo caso particolare (se ho capito bene) vorrei andare per diverse classi, ognuna per il proprio insieme di responsabilità più la classe di front-end che servirebbe da proxy per coloro che sono responsabili di una determinata azione.

Sì, la funzionalità è coesiva, ma ciò non significa che non puoi scomporla in più classi coesive e meno complesse, vero?

    
risposta data 16.08.2012 - 15:22
fonte
0

Per uno, tieni presente che le classi non fanno cose ad altre classi come in "Applica modifiche di configurazione a diversi servizi".

Vedrei quanto sopra come classe ConfigurationChange con potenzialmente diversi tipi derivati come DbChange, PropertyFileChange, ecc. Il servizio sarebbe una classe con un metodo applyConfigurationChange (ConfigurationChange). L'ambiente sarebbe per lo più un coordinatore, che rileva quando si è verificato un ConfigurationChange, creando l'istanza di ConfigurationChange appropriata e passandola ai servizi effettivi.

Sembra anche che ogni Servizio avrebbe "uno" stack di configurazione che supporterà un metodo pushConfiguration () e un metodo popConfiguration () per supportare i numeri 4 e 5 sopra.

L'importante è mantenere le tue lezioni singolarmente focalizzate - se stanno eseguendo più di un comportamento generale, dovresti considerare di suddividere ogni tipo di comportamento in una classe specifica - sia per incapsulare la complessità che per il riutilizzo. Mi piace pensare in questo modo: il codice incorporato in una classe che esegue alcune funzionalità può funzionare benissimo, ma non puoi utilizzarlo da nessun'altra parte e non puoi trasferirlo facilmente quando qualcosa cambia. Il codice in una classe ben progettata che funziona come pubblicizzato (vale a dire ogni funzione fa quello che dice che fa), è facilmente spostata e può essere considerata attendibile. Rendendo i comportamenti una classe separata, si fornisce al comportamento un'API che la separa dalla classe client, fornendo il disaccoppiamento desiderato.

Infine, evita qualsiasi classe che assomigli o funzioni come una classe Manager. In quasi tutti i casi che ho visto, queste classi diventano enormi mostri gonfiati. Piuttosto che avere una classe che gestisce un insieme di classi, progettare ogni classe per gestirsi da sola. Di solito non è una classe che sa più se stessa di se stessa, quindi dovrebbe essere l'unica a gestirsi. Questo è particolarmente vero per le classi che sono Threaded.

Un'altra tecnica che può distruggere enormi classi monolitiche è considerare le singole attività che la classe svolge come classi uniche - classi che vengono istanziate per gestire un'attività specifica, raccogliendo le istanze richieste, eseguendo il lavoro e poi dissolvendosi - un po 'come un modello di spedizione.

    
risposta data 12.02.2013 - 18:25
fonte

Leggi altre domande sui tag