Design for change: accoppiamento e coesione in sistemi orientati agli oggetti

Accoppiamento e coesione sono due termini spesso fraintesi nell'ingegneria del software. Questi sono termini che vengono utilizzati per indicare l'analisi qualitativa della modularità in un sistema, e ci aiutano a identificare e misurare la complessità di progettazione di sistemi orientati agli oggetti.

Tuttavia, una buona conoscenza di entrambi è necessaria per realizzare sistemi che siano scalabili, gestibili e estendibili nel tempo. In questo post, parlerò di entrambi; Presenterò esempi di codice nei miei futuri post su questo argomento.

In che modo differiscono coesione e accoppiamento? In che modo i concetti di coesione e accoppiamento sono correlati a progetti software buoni o poveri? Prima di esplorare la coesione e l'accoppiamento e il modo in cui influiscono sui progetti software, comprendiamo qual è ciascuno di questi concetti e il loro tipo.

Accoppiamento

L'accoppiamento può essere definito come il grado di interdipendenza esistente tra i moduli software e quanto strettamente sono collegati tra loro. In sostanza, l'accoppiamento indica la forza dell'interconnessione tra i moduli software. Quando questo accoppiamento è elevato, possiamo presumere che i moduli software siano interdipendenti, ovvero che non possano funzionare senza l'altro. Esistono diverse dimensioni di accoppiamento:

  • Accoppiamento del contenuto: questo è un tipo di accoppiamento in cui un particolare modulo può accedere o modificare il contenuto di qualsiasi altro modulo. In sostanza, quando un componente passa parametri per controllare l'attività di qualche altro componente, c'è un accoppiamento di controllo tra i due componenti.
  • Accoppiamento comune: questo è un tipo di accoppiamento in cui più moduli hanno accesso a dati globali condivisi
  • Accoppiamento timbro: questo è un tipo di accoppiamento in cui la struttura dei dati viene utilizzata per trasferire le informazioni da un componente del sistema a un altro
  • Accoppiamento di controllo: questo è un tipo di accoppiamento in cui un modulo può modificare il flusso di esecuzione di un altro modulo
  • Accoppiamento dati: in questo tipo di accoppiamento, due moduli interagiscono scambiandosi o trasmettendo dati come parametro

Coesione

Coesione denota il livello di intra-dipendenza tra gli elementi di un modulo software. In altre parole, la coesione è una misura del grado in cui le responsabilità di un singolo modulo o componente formano un'unità significativa. La coesione è dei seguenti tipi:

  • Coesione co-accidentale: questa è una coesione casuale non pianificata che potrebbe essere il risultato della suddivisione di un modulo in moduli più piccoli.
  • Coesione logica: questo è un tipo di coesione in cui più funzioni o elementi dati correlati logicamente sono collocati nello stesso componente
  • Coesione temporale: questo è un tipo di coesione in cui gli elementi di un modulo sono raggruppati in un modo in cui vengono elaborati nello stesso momento. Un esempio potrebbe essere un componente utilizzato per inizializzare un insieme di oggetti.
  • Coesione procedurale - questo è un tipo di coesione in cui le funzioni in un componente sono raggruppate in modo da consentirne l'esecuzione sequenziale e renderle proceduralmente coese
  • Coesione comunicativa: in questo tipo di coesione gli elementi di un modulo sono raggruppati logicamente insieme in modo che vengano eseguiti in modo sequenziale e lavorino sugli stessi dati
  • Coesione sequenziale - in questo tipo di coesione gli elementi di un modulo sono raggruppati in modo tale che l'output di uno di essi diventi l'input del successivo - vengono eseguiti tutti in sequenza. In sostanza, se l'output di una parte di un componente è l'input di un altro, diciamo che il componente ha coesione sequenziale.
  • Coesione funzionale: questo è il tipo di coesione migliore e più preferito in cui il grado di coesione è il più alto. In questo tipo di coesione, gli elementi di un modulo sono raggruppati funzionalmente in un'unità logica e lavorano insieme come un'unità logica - questo promuove anche flessibilità e riusabilità.

Le migliori pratiche

L'accoppiamento stretto aumenta il costo di manutenzione poiché è difficile e le modifiche a un componente influirebbero su tutti gli altri componenti ad esso collegati. Quindi, il refactoring del codice diventa difficile in quanto sarebbe necessario refactoring di tutti gli altri componenti nella catena connessa in modo che la funzionalità non si interrompa. Questo processo è complicato e richiede molto tempo e sforzi noiosi. 

Dovresti progettare classi che contengono il minor numero di variabili di istanza, ovvero, la progettazione della tua classe è "buona" se contiene un numero ridotto di variabili di istanza. Idealmente, ciascuno dei metodi della classe dovrebbe manipolare una o più di queste variabili di istanza. Teoricamente, una classe è massimamente coesa se ciascuna delle variabili di istanza della classe viene utilizzata o manipolata da ciascuno dei metodi di quella classe. Quando la coesione in classe è alta, i metodi ei membri dei dati della classe sono co-dipendenti e lavorano insieme come una singola unità logica. Tuttavia, in realtà non è possibile progettare tali classi o, direi piuttosto, non è consigliabile progettare classi che siano al massimo coese.