Cos'è l'alta coesione e come usarla / realizzarla?


84

Sto imparando la programmazione di computer e in diversi posti mi sono imbattuto nel concetto di coesione e capisco che è auspicabile che un software abbia "alta coesione", ma cosa significa? Sono un programmatore Java, C e Python che impara il C ++ dal libro C ++ Primer che menziona la coesione senza averla nell'indice, potresti indicarmi alcuni link su questo argomento? Non ho trovato la pagina di wikipedia sulla coesione dell'informatica informativa poiché dice solo che è una misura qualitativa e non fornisce esempi di codice reale.



3
Alta coesione: comportamento correlato a sedersi insieme e comportamento non correlato a sedersi altrove.
Teoman shipahi

Risposte:


242

Alta coesione è quando hai una classe che fa un lavoro ben definito. La bassa coesione è quando una classe svolge molti lavori che non hanno molto in comune.

Facciamo questo esempio:

Hai una classe che aggiunge due numeri, ma la stessa classe crea una finestra che mostra il risultato. Questa è una classe poco coesiva perché la finestra e l'operazione di aggiunta non hanno molto in comune. La finestra è la parte visiva del programma e la funzione di aggiunta è la logica dietro di essa.

Per creare una soluzione altamente coesa, dovresti creare una finestra di classe e una somma di classe. La finestra chiamerà il metodo di Sum per ottenere il risultato e visualizzarlo. In questo modo svilupperai separatamente la logica e la GUI della tua applicazione.


14
Onestamente non definisco Coesione in questo modo. La tua definizione è SRP (principio di responsabilità unica). E la coesione riguarda il fatto che le classi che orbitano attorno alle stesse caratteristiche siano vicine o meno l'una all'altra.
v.oddou

4
L'SRP (Single Responsiblity Principle) è solo un altro modo per esprimere lo stesso concetto. La coesione è più una metrica; l'SRP è una linea guida pragmatica che, se seguita, porterà a classi coese.
ComDubh

3
Penso che la finestra della classe non dovrebbe chiamare alcun oggetto della somma della classe poiché il suo unico scopo è di renderlo non ha bisogno di conoscere l '"esistenza" della somma della classe o di qualsiasi altra classe. Dovrebbe esserci un'altra classe che dice Driver che dovrebbe ottenere il risultato da la classe somma e passerebbe il risultato alla classe Finestra per il rendering
Eklavyaa

1
Non lo capisco. Questa non è coesione secondo il codice pulito dello zio Bob. Questo è SRP
karlihnos

Spiegazione molto chiara! Grazie
Vincent Llauderes

55

Una spiegazione di cosa si tratta da Steve McConnell Code Complete di :

La coesione si riferisce a quanto strettamente tutte le routine in una classe o tutto il codice in una routine supportano uno scopo centrale . Classi che contengono funzionalità fortemente correlate sono descritte come dotate di una forte coesione e l'obiettivo euristico è di rendere la coesione il più forte possibile. La coesione è uno strumento utile per gestire la complessità perché più codice in una classe supporta uno scopo centrale, più facilmente il tuo cervello può ricordare tutto ciò che fa il codice.

Un modo per ottenerlo dallo zio Bob Clean Code di :

Le classi dovrebbero avere un file numero limitato di variabili di istanza . Ciascuno dei metodi di una classe dovrebbe manipolare una o più di quelle variabili. In generale, più variabili manipola un metodo, più coerente è il metodo con la sua classe. Una classe in cui ogni variabile viene utilizzata da ciascun metodo è coesa al massimo.

In generale non è né consigliabile né possibile creare classi così coese al massimo; d'altro canto, vorremmo che la coesione fosse alta. Quando la coesione è alta, significa che i metodi e le variabili della classe sono co-dipendenti e rimangono uniti come un tutto logico.

La nozione di coesione è fortemente correlata alla nozione di accoppiamento; inoltre, esiste un principio basato sull'euristica dell'elevata coesione, denominato Single Responsibility Principle (la S di SOLID).


1
Penso che la tua risposta sia più completa di quella accettata, perché descrive sia SRP che coesione, e quindi aiuta a comprendere le specificità e le differenze tra questi due concetti.
The Once-ler

18

L'alta coesione è un concetto di ingegneria del software. Fondamentalmente, dice che una classe dovrebbe fare solo quello che dovrebbe fare, e lo fa completamente. Non sovraccaricarlo con funzioni che non dovrebbe fare, e qualsiasi cosa direttamente correlata ad essa non dovrebbe apparire nemmeno nel codice di qualche altra classe.

L'esempio è abbastanza soggettivo, poiché dobbiamo considerare anche la scala. Un semplice programma non dovrebbe essere troppo modulare o sarà frammentato; mentre un programma complesso può richiedere più livelli di astrazioni per prendersi cura della complessità.

ad es. Classe e-mail. Dovrebbe contenere membri di dati a, da, cc, bcc, subject, body e può contenere questi metodi saveAsDraft (), send (), discardDraft (). Ma login () non dovrebbe essere qui, poiché ci sono un certo numero di protocolli di posta elettronica, e dovrebbe essere implementato separatamente.


È la definizione di SRP: "una classe dovrebbe fare solo quello che dovrebbe fare, e lo fa completamente".
AliN11

11

La coesione viene solitamente misurata utilizzando una delle metriche LCOM (mancanza di coesione), la metrica LCOM originale proveniva da Chidamber e Kemerer. Vedi ad esempio: http://www.computing.dcu.ie/~renaat/ca421/LCOM.html

Un esempio più concreto: se una classe ha ad esempio un campo privato e tre metodi; quando tutti e tre i metodi utilizzano questo campo per eseguire un'operazione, la classe è molto coesa.

Pseudo codice di una classe coesiva:

class FooBar {
  private SomeObject _bla = new SomeObject();

  public void FirstMethod() {
    _bla.FirstCall();
  }

  public void SecondMethod() {
    _bla.SecondCall();
  }

  public void ThirdMethod() {
    _bla.ThirdCall();
  }
}

Se una classe ha ad esempio tre campi privati ​​e tre metodi; quando tutti e tre i metodi utilizzano solo uno dei tre campi, la classe è scarsamente coesa.

Pseudo codice di una classe poco coesa:

class FooBar {
  private SomeObject _bla = new SomeObject();
  private SomeObject _foo = new SomeObject();
  private SomeObject _bar = new SomeObject();

  public void FirstMethod() {
    _bla.Call();
  }

  public void SecondMethod() {
    _foo.Call();
  }

  public void ThirdMethod() {
    _bar.Call();
  }
}

Il principio della classe che fa una cosa è il Principio di responsabilità unica che viene da Robert C. Martin ed è uno dei SOLID principi . Il principio prescrive che una classe debba avere una sola ragione per cambiare.

Rimanere vicini al Principio di Responsabilità Unica potrebbe portare a un codice più coeso, ma a mio parere si tratta di due cose diverse.


4

Questo è un esempio di bassa coesione:

class Calculator
{


     public static void main(String args[])
     {

          //calculating sum here
          result = a + b;
          //calculating difference here
          result = a - b;
          //same for multiplication and division
     }
}

Ma un'elevata coesione implica che le funzioni nelle classi facciano quello che dovrebbero fare (come vengono chiamate). E non una funzione che svolge il lavoro di un'altra funzione. Quindi, il seguente può essere un esempio di alta coesione:

class Calculator
{


     public static void main(String args[])
     {

          Calculator myObj = new Calculator();
          System.out.println(myObj.SumOfTwoNumbers(5,7));
      }


     public int SumOfTwoNumbers(int a, int b)
     {

          return (a+b);
     }

     //similarly for other operations

}

3

Un modo generale di pensare al principio di coesione è quello di individuare un codice insieme ad altro codice che dipende da esso o da cui dipende. La coesione può e deve essere applicata a livelli di composizione superiori al livello di classe. Ad esempio, un pacchetto o uno spazio dei nomi dovrebbe idealmente contenere classi che si riferiscono a qualche tema comune e che sono più fortemente interdipendenti che dipendenti da altri pacchetti / spazi dei nomi. Vale a dire mantenere le dipendenze locali.


1

coesione significa che una classe o un metodo svolge solo un lavoro definito. anche il nome del metodo o della classe dovrebbe essere autoesplicativo. per esempio, se scrivi una calcolatrice dovresti chiamare la classe "calcolatrice" e non "asdfghj". inoltre dovresti considerare di creare un metodo per ogni attività, es. sottract () add () ecc ... il programmatore che potrebbe usare il tuo programma in futuro sa esattamente cosa stanno facendo i tuoi metodi. una buona denominazione può ridurre gli sforzi per i commenti

anche un principio è ASCIUTTO - non ripetere te stesso


1

Il termine coesione è stato originariamente utilizzato per descrivere i moduli del codice sorgente come misura qualitativa di quanto bene il codice sorgente del modulo fosse correlato tra loro. L'idea di coesione è utilizzata in una varietà di campi. Ad esempio, un gruppo di persone come un'unità militare può essere coeso, il che significa che le persone nell'unità lavorano insieme per un obiettivo comune.

L'essenza della coesione del codice sorgente è che il codice sorgente in un modulo lavora insieme verso un obiettivo comune e ben definito. La quantità minima di codice sorgente necessaria per creare gli output del modulo è nel modulo e non di più. L'interfaccia è ben definita e gli input fluiscono attraverso l'interfaccia e le uscite fluiscono di nuovo attraverso l'interfaccia. Non ci sono effetti collaterali e l'enfasi è sul minimalismo.

Un vantaggio dei moduli coesi dal punto di vista funzionale è che lo sviluppo e l'automazione di unit test è semplice. In effetti, una buona misura della coesione di un modulo è la facilità con cui è possibile creare una serie completa di unit test esaustivi per il modulo.

Un modulo può essere una classe in un linguaggio orientato agli oggetti o una funzione in un linguaggio funzionale o non orientato agli oggetti come C. Gran parte del lavoro originale in quest'area di misurazione della coesione riguardava principalmente il lavoro con i programmi COBOL presso IBM nel Anni '70 quindi la coesione non è sicuramente solo un concetto orientato agli oggetti.

L'intento originale della ricerca da cui provenivano il concetto di coesione e il concetto associato di accoppiamento era la ricerca di quali fossero le caratteristiche dei programmi che erano facili da capire, mantenere ed estendere. L'obiettivo era essere in grado di apprendere le migliori pratiche di programmazione, codificare quelle migliori pratiche e quindi insegnare le pratiche ad altri programmatori.

L'obiettivo di un buon programmatore è scrivere codice sorgente la cui coesione sia la più alta possibile dato l'ambiente e il problema da risolvere. Ciò implica che in un'applicazione di grandi dimensioni alcune parti del corpo del codice sorgente varieranno da altre parti per quanto riguarda il livello di coesione del codice sorgente in quel modulo o classe. A volte il meglio che puoi ottenere è la coesione temporale o sequenziale a causa del problema che stai cercando di risolvere.

Il miglior livello di coesione è la coesione funzionale. Un modulo con coesione funzionale è simile a una funzione matematica in quanto fornisci un insieme di input e ottieni un output specifico. Un modulo veramente funzionale non avrà effetti collaterali oltre all'output né manterrà alcun tipo di stato. Avrà invece un'interfaccia ben definita che incapsula la funzionalità del modulo senza esporre nessuna delle parti interne del modulo e la persona che utilizza il modulo fornirà un particolare insieme di input e riceverà un particolare output in cambio. Un modulo veramente funzionale dovrebbe essere anche thread-safe.

Molte librerie di linguaggi di programmazione contengono una serie di esempi di moduli funzionali che siano classi, modelli o funzioni. Gli esempi coesivi più funzionali sarebbero funzioni matematiche come seno, coseno, radice quadrata, ecc.

Altre funzioni possono avere effetti collaterali o mantenere uno stato di qualche tipo risultando nel rendere più complicato l'uso di tali funzioni.

Ad esempio una funzione che genera un'eccezione o imposta una variabile di errore globale ( errnoin C) o deve essere utilizzata in una sequenza (strtok() funzione è un esempio dalla libreria C standard poiché mantiene uno stato interno) o che fornisce un puntatore che deve quindi essere gestiti o rilasciare un log a qualche utility di log sono tutti esempi di una funzione che non è più funzionale alla coesione.

Ho letto sia il libro originale di Yourdon che quello di Constantine, Structured Programming, dove mi sono imbattuto per la prima volta nell'idea di coesione negli anni '80 e il libro di Meilir Page-Jones Practical Guide to Structured Systems Design, e Page-Jones ha fatto un lavoro molto migliore nel descrivere sia accoppiamento che coesione. Il libro di Yourdon e Constantine sembra un po 'più accademico. Il libro di Steve McConnell Code Complete è abbastanza buono e pratico e l'edizione rivista ha molto da dire sulle buone pratiche di programmazione.


Dici che The minimum amount of source code needed to create the module outputs is in the module and no morequesto non è correlato a Coesione ma a DTSTTCPW
v.oddou

@ v.oddou, la quantità minima di codice è effettivamente correlata a Coesione. Più codice in un modulo non è correlato all'output del modulo, più è probabile che il codice abbia effetti collaterali, quindi Coesione inferiore. Ogni concetto ha prospettive diverse, in particolare concetti come Coesione che sono alquanto ambigui. Le misurazioni per la coesione sono qualitative che richiedono una sorta di logica fuzzy per allocare un particolare modulo a una categoria o a un'altra utilizzando una rubrica di qualche tipo. Dire un codice minimo per le uscite non è una caratteristica sufficiente per un'alta coesione solo una delle tante.
Richard Chambers,

1

La maggior parte delle risposte non spiega cosa sia la coesione, è ben definita nel codice pulito del libro di zio Bob.

Le classi dovrebbero avere un numero limitato di variabili di istanza. Ciascuno dei metodi di una classe dovrebbe manipolare una o più di quelle variabili. In generale, più variabili un metodo manipola, più coerente è il metodo con la sua classe. Una classe in cui ogni variabile viene utilizzata da ciascun metodo è coesa al massimo. In generale non è né consigliabile né possibile creare classi così coese al massimo; d'altro canto, vorremmo che la coesione fosse alta. Quando la coesione è alta, significa che i metodi e le variabili della classe sono co-dipendenti e rimangono uniti come un tutto logico.

Lasciatemi spiegare con una definizione di classe

class FooBar {
private _bla;
private _foo;
private _bar;

function doStuff()

   if(this._bla>10){
     this._foo = 10;
     this._bar = 20;
   }

}
function doOtherStuff(){

    if(this._foo==10){
       this._bar = 100;
       this._bla = 200;
    }
}

}

Se vedi l'esempio sopra, la classe è coesa, il che significa che le variabili sono condivise tra la classe per lavorare insieme più variabili sono condivise, il che significa che la classe è altamente coesa e funziona come una singola unità.


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.