Sono uno studente che è entrato di recente in unazienda di sviluppo software come stagista. Al ritorno alluniversità, uno dei miei professori diceva che dobbiamo sforzarci di ottenere “Basso accoppiamento e alta coesione”.

Capisco il significato di basso accoppiamento. Significa mantenere il codice di componenti separati separatamente, in modo che un cambiamento in un punto non rompa il codice in un altro.

Ma cosa si intende per alta coesione. Se significa integrare bene tra loro i vari pezzi dello stesso componente, non capisco come questo diventi vantaggioso.

Cosa si intende per alta coesione? Si può spiegare un esempio per comprenderne i vantaggi?

Commenti

  • possibile duplicato di Ci sono Metriche per la coesione e laccoppiamento?
  • Larticolo di Wikipedia non risponde sufficientemente alla tua domanda? en.wikipedia.org/wiki/Cohesion_(computer_science)
  • Cè un buon articolo su questo a: msdn.microsoft.com/en-us/magazine/cc947917.aspx
  • @EoinCarroll: Purtroppo larticolo di wikipedia al momento non dà nulla di buono esempi concreti con cui i nuovi programmatori possono lavorare. La teoria è buona e basta, ma ' non resta fedele fino a quando ' non hai commesso gli errori relativi alla bassa coesione. Lalta coesione è uno di quegli argomenti che mi ha richiesto diversi anni di programmazione per comprendere appieno perché è importante e come ottenerla.
  • Non ho mai capito veramente Coesione finché non ho letto Codice pulito. Dovresti farlo anche tu.

Risposta

Un modo per guardare alla coesione in termini di OO è se i metodi in la classe sta utilizzando uno qualsiasi degli attributi privati. Utilizzando metriche come LCOM4 (Lack of Cohesive Methods), come sottolineato da gnat in questa risposta qui , puoi identificare le classi che potrebbero essere modificate. Il motivo per cui desideri effettuare il refactoring di metodi o classi per essere più coesi è che semplifica la progettazione del codice per altri utenti . Fidati di me; la maggior parte dei responsabili tecnici e dei programmatori di manutenzione ti adoreranno quando risolverai questi problemi.

Puoi utilizzare strumenti nel tuo processo di creazione come Sonar per identificare una bassa coesione nella base del codice. Ci sono un paio di casi molto comuni a cui posso pensare in cui i metodi sono bassi in “coesione” :

Caso 1: il metodo non è affatto correlato alla classe

Considera il seguente esempio:

 public class Food { private int _foodValue = 10; public void Eat() { _foodValue -= 1; } public void Replenish() { _foodValue += 1; } public void Discharge() { Console.WriteLine("Nnngghhh!"); } }  

Uno dei metodi , Discharge(), manca di coesione perché non “tocca nessuno dei membri privati della classe”. In questo caso è presente un solo membro privato: _foodValue. Se non fa nulla con le parti interne della classe, allora appartiene davvero a quella classe? Il metodo potrebbe essere spostato in unaltra classe che potrebbe essere chiamata ad esempio FoodDischarger.

 // Non-cohesive function extracted to another class, which can // be potentially reused in other contexts public FoodDischarger { public void Discharge() { Console.WriteLine("Nnngghhh!"); } }  

In te “lo fai in Javascript, poiché le funzioni sono oggetti di prima classe, lo scarico può essere una funzione gratuita:

 function Food() { this._foodValue = 10; } Food.prototype.eat = function() { this._foodValue -= 1; }; Food.prototype.replenish = function() { this._foodValue += 1; }; // This Food.prototype.discharge = function() { console.log("Nnngghhh!"); }; // can easily be refactored to: var discharge = function() { console.log("Nnngghhh!"); }; // making it easily reusable without creating a class  

Caso 2: classe di utilità

Questo è in realtà un caso comune che rompe la coesione. Tutti amano le classi di utilità, ma queste di solito indicano difetti di progettazione e la maggior parte delle volte rendono la base di codice più difficile da mantenere (a causa dellelevata dipendenza associata alle classi di utilità). Considera le seguenti classi:

 public class Food { public int FoodValue { get; set; } } public static class FoodHelper { public static void EatFood(Food food) { food.FoodValue -= 1; } public static void ReplenishFood(Food food) { food.FoodValue += 1; } }  

Qui possiamo vedere che la classe di utilità ha bisogno per accedere a una proprietà nella classe Food. I metodi nella classe utility non hanno alcuna coesione in questo caso perché ha bisogno di risorse esterne per fare il suo lavoro. In questo caso, non sarebbe meglio avere i metodi nella classe con cui stanno lavorando ( proprio come nel primo caso)?

Caso 2b: Oggetti nascosti nelle classi di utilità

Cè un altro caso di classi di utilità in cui sono presenti oggetti di dominio non realizzati. La prima reazione istintiva un programmatore ha quando programma la manipolazione di stringhe deve scrivere una classe di utilità per essa.Come quella qui che convalida un paio di rappresentazioni di stringa comuni:

 public static class StringUtils { public static bool ValidateZipCode(string zipcode) { // validation logic } public static bool ValidatePhoneNumber(string phoneNumber) { // validation logic } }  

Cosa la maggior parte non si rende conto che qui un codice postale, un numero di telefono o qualsiasi altra rappresentazione di stringa può essere un oggetto a sua volta:

 public class ZipCode { private string _zipCode; public bool Validates() { // validation logic for _zipCode } } public class PhoneNumber { private string _phoneNumber; public bool Validates() { // validation logic for _phoneNumber } }  

Lidea che non dovresti” t “gestire le stringhe” direttamente è descritta in questo post di @codemonkeyism , ma è strettamente correlato alla coesione perché il modo in cui i programmatori usano le stringhe inserendo la logica nelle classi di utilità.

Commenti

Risposta

Alta coesione significa tenere insieme cose simili e correlate, accoppiare o fondere parti che condividono contenuto, funzionalità, motivo o obiettivo . In altre parole, bassa coesione potrebbe ad esempio significare una funzione / classe / entità di codice che serve a più scopi piuttosto che essere “ al punto “. Una delle idee portanti è fare una cosa e farla bene . Altri potrebbero includere il fatto ovvio che non si replicano funzionalità simili in molti posti. Questo migliora anche la località del codice base, certi tipi di cose si trovano in un certo posto (file, classe, set di funzioni, …) piuttosto che essere sparpagliata.

Come esempio, si consideri una classe che ha due o tre scopi: carica / memorizza risorse (ad esempio un file) e quindi analizza e visualizza il Una tale classe ha una bassa coesione perché gestisce almeno due compiti separati che non sono affatto correlati (I / O di file, analisi e visualizzazione). Un progetto ad alta coesione potrebbe utilizzare classi distinte per caricare e memorizzare la risorsa, analizzarla e quindi visualizzarla.

Daltra parte, laccoppiamento basso mira a mantenere separate le cose distinte, in modo che interagiscano tra loro. il meno possibile, il che riduce la complessità e semplifica il design.

Risposta

Significa che le parti di un oggetto sono strettamente correlate alla funzione delloggetto. Ciò significa che cè uno spreco minimo o nullo allinterno delloggetto in termini di funzione o responsabilità. Questo a sua volta può migliorare la comprensione del motivo per cui loggetto in questione dovrebbe essere utilizzato.

Commenti

  • non ' si applica anche a un livello superiore rispetto ai semplici oggetti? es. raggruppare oggetti / funzioni relativi a unattività in spazi dei nomi?

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *