Login
Cerca all'interno di JavaPortal
Help
Home Page Documentazione Forum Progetti Partner Pubblica!
Documentazione > Tutorial > [GRASP] Pattern High Cohesion
Hide
Best Practices
EJB
Frameworks
Howto
J2EE
J2ME and Wireless
J2SE
JSP e Servlet
Java Application Server
Java IDE/Tools
Java Media
Java Security
Java Sys Admin
Java e XML
Java e SQL
OpenSource Java
Patterns
Repository
Tesi
UML
Web Services
Slide
White Paper di jws.it
project management
Eventi
Groovy

Hai una tesi in Java?
Tesine preparate
per esami?
Pubblica tutto su
JavaPortal!

Scrivi al nostro staff


Sconto del 15% al JaxItalia


Un giorno le macchine riusciranno...
a risolvere tutti i problemi, ma mai nessuna di esse potra' porne uno. Einstein


Convention over configuration


Rss Feed
Home Page
Articoli
News
Forum
Classi

  Visualizza Commenti (0) Aggiungi Commento    
Add to Shortcuts
 
Vota l'articolo
[GRASP] Pattern High Cohesion
By Luana Rinaldi
21 maggio 2008

  [GRASP] Pattern High Cohesion
Program Problema: Come mantenere gli oggetti focalizzati, comprensibili e gestibili, sostenendo parallelamente un basso accoppiamento?
Program Soluzione
Program Conseguenze
Program Esempio
Program Pattern Correlati
Program Conclusioni
Program Bibliografia

La coesione è una misura di quanto fortemente diverse responsabilità siano correlate e concentrate in un qualsiasi elemento del progetto, come ad esempio una classe o un insieme di esse.  Una classe, ad esempio, dovrebbe svolgere compiti limitati, relativi ad una ben precisa responsabilità. Molto spesso invece si possono riscontrare classi che svolgono svariati compiti, non correlati tra loro: in questi casi, le classi prodotte presentano una bassa coesione e risultano difficili da isolare, complesse da riutilizzare e manutenere, e costituiscono elementi critici in caso di cambiamenti del codice. I problemi principali a cui vanno incontro questo genere di casi sono:

  • Scarsa riusabilità
  • Scarsa comprensibilità
  • Scarsa manutenibilità
Non esiste in generale una misura di quanto debba essere coesiva una classe, ma è comunque possibile individuare diversi livelli di coesione in base alla quantità e alla qualità di responsabilità delegate alla singola classe. I livelli sono:
  • Coincidental: moduli composti da molte parti non correlate tra loro;
  • Logical: moduli composti da parti logicamente correlate tra loro, ma senza nessuna interazione tra di esse
  • Temporal: elementi raggruppati in un modulo solo perchè vengono eseguiti tutti nel medesiomo periodo temporale;
  • Procedural: moduli composti da componenti che svolgono un intero flusso di lavoro
  • Communicational: elementi che operano sullo stesso input oppure producono lo stesso output;
  • Sequential: le componenti sono organizzate in modo che l’output di una procedura costituisca l’input della successiva
  • Informational: molte funzioni dello stesso modulo hanno accesso alla stessa struttura dati o risorsa che è nascosta attaverso il modulo stesso
  • Functional:  il modulo ha la responsabilità di una sola azione, o di raggiungere un solo obiettivo. Tutte le parti del modulo contribuiscono a questa funzione, e nessuna di essa è estranea all’obiettivo
Di quelli elencati, solo gli ultimi due possono essere definiti livelli di buna coesione, mentre il livello 6 può essere in alcuni casi accettabile.

Passiamo ora alla definizione formale del Pattern High Cohesion:

Nome:    High Cohesion
Problema:   Come mantenere gli oggetti focalizzati, comprensibili e gestibili, sostenendo parallelamente un basso accoppiamento?
Soluzione:    Assegnazione delle responsabilità in modo tale che l’accoppiamento non necessario rimanga basso.

Affrontiamo più nel dettaglio la specifica del pattern. 

 



Problema: Come mantenere gli oggetti focalizzati, comprensibili e gestibili, sostenendo parallelamente un basso accoppiamento? top
Come è già stato detto, high cohesion non è esattamente un pattern, ma più un principio di progettazione da tener presente nelle fasi iniziali. Ma una volta superata la fase di progettazione, è comunque necessario tenere sotto controllo il codice in modo da evitare la diminuzione di coesione durante l’implementazione. Di conseguenza, dovrebbero essere costantemente monitorati:  
  •  Metodi: numero delle line of code ( non dovrebbero superare le 100) 
  •  Classi: numero di metodi presenti ( non dovrebbero essere ne troppi ne troppo pochi)
  •  Metodi e Classi: nomi ( non dovrebbe essere difficile assegnare un nome)
  •  Metodi : passaggio di parametri (il comportamento di un metodo non dovrebbe dipendere dal tipo di parametri in input)

Se viene riscontrata anche soltanto una di queste situazioni, probabilmente l’elemento implementato presenta bassa coesione, quindi sarà necessario operare in modo da riportare l’elemento stesso ad un livello di coesione accettabile.



Soluzione top
Purtroppo non esistono regole stabilite da seguire per poter rispettare i principi di coesione, ma è comunque seguire alcune linee guida di base per poter evitare situazioni come quelle descritte sopra.

Controllo Dimensioni: si possono definire delle dimensioni massime di ogni elemento da tener presente per evitare di assegnare ad esso troppe responsabilità. In generale, un metodo coesivo raramente supererà le 100 righe di codice, ed in media sarà di circa 40/50. Una classe coesiva difficilmente potrà avere più di 10/20 metodi. Un package coesivo non potrà consistere di 1000 classi.

 Assegnazione Nomi: la difficoltà di assegnazione di un nome ad un elemento è in genere sintomo di scarsa coesività, in quanto può significare che quell’elemento ha troppe responsabilità. Ad esempio, raggruppare tutte le classi in un package utils costituisce un classico esempio di bassa coesione.

Numero Parametri: Normalmente il numero di parametri in ingresso ad un metodo dovrebbe essere in misura ridotta. Ancora più importante controllare, invece, è la gestione del comportamento del metodo a seconda del valore di un determinato parametri in input: questa situazione dovrebbe essere evitata progettando meglio l’intera classe (potrebbe costituire una soluzione l’applicazione del pattern Template Method, di cui si parlerà in seguito).

E’ necessario sottolineare, comunque, che queste linee guida andrebbero comunque seguite con criterio, ossia bilanciando il livello di coesione con l’esplosione di classi e metodi che svolgono responsabilità troppo limitate.



Conseguenze top
La corretta applicazione di questo pattern comporta numerosi vantaggi in termini di manutenibilità e riusabilità del codice. Infatti, una classe altamente coesa svolge una ben determinata funzione, quindi in caso di errori si può facilmente localizzarne la causa; inoltre, in caso di necessità, la stessa classe può essere utilizzata come componente per svolgere altre funzioni che necessitano delle operazioni implementate nella classe stessa. Bisogna comunque bilanciare l’utilizzo di questo pattern con le esigenze di progetto, in modo da valutare gli eventuali impatti di un abbassamento di coesione per esigenze progettuali.

Implicitamente, comunque, il pattern high cohesion implica anche un basso accoppiamento, e quindi il rispetto del pattern Low Coupling.


Esempio top
Supponiamo di dover creare una classe che si occupa della stampa di un report, passato in ingresso sottoforma di oggetto Java. Supponiamo inoltre che il sistema debba supportare diversi formati di stampa, come ad esempio PDF, DOC, XSL e così via. Si potrebbe prevedere una implementazione come la seguente:

public class PrintManager{
    private final int PDF =0;
    private final int DOC = 1;
    private final int XLS = 2;
    
    private void print(Object o, int printType){
        switch(printType){
            case PDF:
                //doSomething
                break;
            case DOC:
                //doSomething
                break;
            case XLS:
                //doSomething
                break;        
            default
                //doSomething
                break;                        
        }
    }
}


Come si può vedere, questa classe presenta un unico metodo print() che accetta in ingresso una variabile da cui derivare il formato di stampa attraverso un blocco switch. Questa situazione è fortemente sconsigliata, in quanto si sta demandando ad un metodo di modificare il proprio comportamento in base al valore assunto dalla variabile printType. La situazione corretta potrebbe essere la seguente:

public class PrintManager{
    
    private void printPDF(Object o){
        //doSomething
    }
    private void printDOC(Object o){
        //doSomething
    }
    private void printXLS(Object o){
        //doSomething
    }
}


Un’ulteriore raffinamento potrebbe essere fatto identificando le parti comuni dei tre metodi ( come ad esempio la formattazione delle variabili dell’oggetto) e inserire questa logica in un metodo comune o in una superclasse, utilizzando poi il pattern Template Method o la stessa ereditarietà per gestire i differenti formati.  



Pattern Correlati top

Patern Low Coupling (GRASP)

Pattern Template Method (GOF)



Conclusioni top

In questo articolo abbiamo presentato il pattern High Cohesion. Nel prossimo articolo parleremo del pattern Controller.



Bibliografia top

[1] Low Coupling Pattern di Ugo Landini

[2] Applying GRASP to Object Design - Creator GRASP Pattern - Who is responsible for creating a class? - Applying UML and Patterns

[3] Gamma, Erich. “Object Oriented Software Development based on ET++: Design Patterns, Classe Library, Tools.”  Tesi di Dottorato, University of Zurich, Institut Fur Informatik, 1991.

[4] Gamma, Helm, Johnson, Vlissides. “Design Patterns: Elements of Reusable Object-Oriented Software”, Pearson Education Inc., 1995.

[5] Larman, Craig. “Applying UML and Patterns :An Introduction to Object-Oriented Analysis and Design and the Unified Process”, Pearson Education Inc., 2005.

[6] Object Management Group, 2003. UML 2.0 Superstructure Specification. www.uml.org.



Username:
Password:
To sign up for an account, click register... Register
Hide





Powered By



Campagna Anti-IF


Skin


PARTNER
Zio Budda
HostingJava


LICENZA



Eccetto dove diversamente specificato, i contenuti di questo sito sono rilasciati sotto licenza Creative Commons

Sitemap  © 2002-2004 Copyright Information. Privacy . Today is domenica 1 agosto 2010