Qual è la differenza tra accoppiamento libero e accoppiamento stretto nel paradigma orientato agli oggetti?

Qualcuno può descrivere la differenza esatta tra accoppiamento libero e accoppiamento stretto nel paradigma orientato agli oggetti?

L’accoppiamento stretto è quando un gruppo di classi è fortemente dipendente l’uno dall’altro.

Questo scenario si verifica quando una class assume troppe responsabilità o quando una preoccupazione si sviluppa su più classi piuttosto che avere una propria class.

L’accoppiamento lento è ottenuto attraverso un design che promuove la responsabilità singola e la separazione delle preoccupazioni.

Una class liberamente accoppiata può essere consumata e testata indipendentemente da altre classi (concrete).

Le interfacce sono un potente strumento da utilizzare per il disaccoppiamento. Le classi possono comunicare attraverso interfacce piuttosto che altre classi concrete e qualsiasi class può trovarsi dall’altra parte della comunicazione semplicemente implementando l’interfaccia.

Esempio di accoppiamento stretto:

class CustomerRepository { private readonly Database database; public CustomerRepository(Database database) { this.database = database; } public void Add(string CustomerName) { database.AddRow("Customer", CustomerName); } } class Database { public void AddRow(string Table, string Value) { } } 

Esempio di accoppiamento libero:

 class CustomerRepository { private readonly IDatabase database; public CustomerRepository(IDatabase database) { this.database = database; } public void Add(string CustomerName) { database.AddRow("Customer", CustomerName); } } interface IDatabase { void AddRow(string Table, string Value); } class Database : IDatabase { public void AddRow(string Table, string Value) { } } 

Un altro esempio qui .

Spiegazione del concetto senza codice

Esempio di riepilogo:

Il cappello è “liberamente accoppiato” al corpo. Ciò significa che puoi facilmente togliere il cappello senza apportare modifiche alla persona / al corpo. Quando puoi farlo, allora hai un “accoppiamento lento”. Vedi sotto per l’elaborazione.

Il cappello è

Accoppiamento stretto (esempio dettagliato)

Pensa alla tua pelle. È attaccato al tuo corpo. Si adatta come un guanto. Ma cosa succederebbe se volessi cambiare il colore della tua pelle da bianco a nero? Riesci a immaginare quanto sarebbe doloroso strapparti la pelle, tingerla e poi ricollegarla ecc.? Cambiare la pelle è difficile perché è strettamente accoppiato al tuo corpo. Non puoi semplicemente apportare modifiche facilmente. Dovresti sostanzialmente ridisegnare un essere umano per renderlo ansible.

  • Punto chiave n. 1 : In altre parole, se vuoi cambiare la pelle, dovresti anche cambiare il disegno del tuo corpo perché i due sono uniti – sono strettamente accoppiati.

Dio non era un buon programmatore orientato agli oggetti.

Accoppiamento lento (Esempio dettagliato)

Ora pensa di vestirti al mattino. Non ti piace il blu? Nessun problema: puoi invece indossare una maglia rossa. Puoi farlo facilmente e senza sforzo perché la camicia non è realmente collegata al tuo corpo allo stesso modo della tua pelle. La maglietta non sa o si preoccupa di quale corpo sta succedendo . In altre parole, puoi cambiare i vestiti, senza veramente cambiare il tuo corpo.

  • Questo è il punto chiave n. 2. Se cambi la camicia, non sei obbligato a cambiare il tuo corpo – quando puoi farlo, allora hai un accoppiamento lento. Quando non puoi farlo, hai un accoppiamento stretto.

Questo è il concetto di base in poche parole.

Perché tutto questo è importante?

È importante perché il software cambia continuamente. In generale, vuoi essere in grado di modificare facilmente il tuo codice.

ad esempio esempi pratici

  • Se qualcuno vuole il loro output in un file CSV piuttosto che in JSON ecc., O se vuoi passare da MySQL a PostGreSQL dovresti essere in grado di apportare queste modifiche con estrema facilità nel tuo codice, senza dover riscrivere l’intera class e passare 10 ore debug. In altre parole, non si desidera accoppiare strettamente l’applicazione con un’implementazione specifica del database (ad esempio Mysql) o con un particolare output (ad esempio file CSV). Perché, come è inevitabile nel software, i cambiamenti arriveranno. Quando arrivano, è molto più facile se le parti del tuo codice sono accoppiate liberamente.
  • Se qualcuno vuole la propria auto in nero , non è necessario ridisegnare l’intera vettura per farlo. Un’auto e le sue parti di ricambio sarebbero un perfetto esempio di architettura liberamente accoppiata (come da commenti di @ mnmopazem). Se vuoi sostituire il tuo motore con uno migliore, dovresti essere in grado di rimuovere semplicemente il tuo motore senza troppi sforzi e scambiarlo con uno migliore. Se la tua auto funziona solo con i motori Rolls Royce ABC2000 e nessun altro motore, la tua auto sarà strettamente accoppiata a quel motore (Rolls Royce ABC200). Sarebbe meglio se avessi cambiato il design della tua auto in modo che funzionasse con qualsiasi motore, in modo che fosse un po ‘più sciolto con i suoi componenti. Ancora meglio sarebbe se la tua auto potesse funzionare senza bisogno di un motore! Un certo numero di accoppiamenti sta per accadere, ma dovrebbe funzionare per minimizzarlo il più ansible, perché quando cambiano i requisiti dovremmo essere ancora in grado di fornire software di buona qualità, molto rapidamente.

Sommario

In breve, l’accoppiamento lento rende il codice più facile da modificare. Le risposte sopra forniscono un codice che vale la pena leggere a questo punto.

Attribuzione dell’immagine .

Nella progettazione orientata agli oggetti, la quantità di accoppiamento si riferisce a quanto il design di una class dipende dal design di un’altra class. In altre parole, con quale frequenza i cambiamenti nella class A cambiano in relazione alla forza nella class B? Accoppiamento stretto significa che le due classi cambiano spesso insieme, l’accoppiamento libero significa che sono per lo più indipendenti. In generale, è consigliabile l’accoppiamento libero perché è più facile da testare e mantenere.

È ansible trovare questo documento di Martin Fowler (PDF) utile.

Discreta differenza di programma tra accoppiamento stretto e accoppiamento lento?

Accoppiamento stretto tra oggetti Java

 class Traveler { Car c=new Car(); void startJourney() { c.move(); } } class Car { void move() { // logic... } } 

Accoppiamento lento tra oggetti Java

 class Traveler { Vehicle v; public void setV(Vehicle v) { this.v = v; } void startJourney() { v.move(); } } 

// ========================= Interfaccia ====================== ==============

  Interface Vehicle { void move(); } 

// ==================== Interfaccia multi-veicolo per attrezzi di class. Prima class ====

 class Car implements Vehicle { public void move() { // logic } } 

// =================== Seconda class ================

 class Bike implements Vehicle { public void move() { // logic } } 

In generale, Tight Coupling è negativo, ma il più delle volte, poiché riduce la flessibilità e la riutilizzabilità del codice, rende le modifiche molto più difficili, impedisce la testabilità, ecc.

L’object strettamente unito è un object che deve conoscere abbastanza l’un l’altro e di solito sono altamente dipendenti l’uno dall’altro. Cambiare un object in un’applicazione strettamente accoppiata spesso richiede modifiche a un numero di altri oggetti. Nella piccola applicazione possiamo facilmente identificare i cambiamenti e ci sono meno possibilità di perdere qualcosa. Ma nelle grandi applicazioni queste interdipendenze non sono sempre conosciute da ogni programmatore o la possibilità di perdere i cambiamenti. Ma ogni insieme di oggetti liberamente accoppiati non dipende dagli altri.

In breve, possiamo dire che l’accoppiamento libero è un objective di progettazione che cerca di ridurre le interdipendenze tra i componenti di un sistema con l’objective di ridurre il rischio che i cambiamenti in un componente richiederanno cambiamenti in qualsiasi altro componente. L’accoppiamento lento è un concetto molto più generico inteso ad aumentare la flessibilità di un sistema, renderlo più manutenibile e rendere l’intero quadro più “stabile”.

Accoppiamento si riferisce al grado di conoscenza diretta che un elemento ha di un altro. possiamo dire un esempio: A e B, solo B cambia il suo comportamento solo quando A cambia il suo comportamento. Un sistema liberamente accoppiato può essere facilmente suddiviso in elementi definibili.

Quando due oggetti sono accoppiati liberamente, possono interagire ma hanno poca conoscenza l’uno dell’altro.

I design liberamente accoppiati ci permettono di build sistemi OO flessibili in grado di gestire il cambiamento.

Il modello di progettazione degli osservatori è un buon esempio per rendere le classi liberamente accoppiate, puoi darci un’occhiata su Wikipedia .

Per come la vedo io, quell’architettura strettamente accoppiata non offre molta flessibilità per il cambiamento se confrontata con un’architettura liberamente accoppiata.

Ma in caso di architetture liberamente accoppiate, formati di messaggio o piattaforms operative o revamping la logica di business non ha impatto sull’altra estremità. Se il sistema viene rimosso per un aggiornamento, ovviamente l’altra estremità non sarà in grado di accedere al servizio per un po ‘ma, a parte questo, la fine invariata può riprendere lo scambio di messaggi come era prima del rinnovo.

Un estratto dal mio post sul blog sull’accoppiamento:

Cos’è l’ accoppiamento stretto : –

Come sopra definizione un object strettamente accoppiato è un object che deve conoscere altri oggetti e di solito sono altamente dipendenti dalle rispettive interfacce.

Quando cambiamo un object in un’applicazione strettamente accoppiata, spesso richiede modifiche a un numero di altri oggetti. Non c’è alcun problema in una piccola applicazione possiamo facilmente identificare il cambiamento. Ma nel caso di grandi applicazioni queste interdipendenze non sono sempre conosciute da tutti i consumatori o da altri sviluppatori o ci sono molte possibilità di cambiamenti futuri.

Prendiamo un codice demo del carrello per capire l’accoppiamento stretto:

 namespace DNSLooseCoupling { public class ShoppingCart { public float Price; public int Quantity; public float GetRowItemTotal() { return Price * Quantity; } } public class ShoppingCartContents { public ShoppingCart[] items; public float GetCartItemsTotal() { float cartTotal = 0; foreach (ShoppingCart item in items) { cartTotal += item.GetRowItemTotal(); } return cartTotal; } } public class Order { private ShoppingCartContents cart; private float salesTax; public Order(ShoppingCartContents cart, float salesTax) { this.cart = cart; this.salesTax = salesTax; } public float OrderTotal() { return cart.GetCartItemsTotal() * (2.0f + salesTax); } } } 

Problemi con l’esempio precedente

Tight Coupling crea alcune difficoltà.

Qui, i metodi OrderTotal() ci danno l’importo completo per gli articoli correnti dei carrelli. Se vogliamo aggiungere le funzionalità di sconto in questo sistema di carrelli. È molto difficile da fare nel codice sopra perché dobbiamo apportare modifiche ad ogni class poiché è strettamente connessa.

Esistono alcuni strumenti che forniscono l’iniezione delle dipendenze attraverso la loro libreria, ad esempio in .net abbiamo la libreria ninject .

Se andrai oltre a java, la spring fornirà queste capacità.

Gli oggetti liberamente accoppiati possono essere creati introducendo interfacce nel codice, questo è ciò che fanno queste fonti.

Dì nel tuo codice che stai scrivendo

 Myclass m = new Myclass(); 

ora questa affermazione nel tuo metodo dice che sei dipendente da myclass questo è chiamato strettamente accoppiato. Ora fornisci un’iniezione del costruttore, o un’iniezione di proprietà e un object di istanziazione, quindi si accoppierà liberamente.

Accoppiamento allentato significa che il grado di dipendenza tra due componenti è molto basso Ex.GSM SIM Accoppiamento stretto significa che il grado di dipendenza tra due componenti è molto alto. ex. CDMA mobile

L’accoppiamento lento è e risponde a dipendenze hardcoded di vecchio stile e problemi correlati come la frequente ricompilazione quando qualcosa cambia e riuso del codice. Sottolinea l’implementazione della logica di lavoro nei componenti ed evita il codice di cablaggio specifico della soluzione.

Loose Coupling = IoC Vedi questo per una spiegazione più semplice.

Loose Coupling è il processo per dare alla dipendenza la tua class ha bisogno indirettamente, senza fornire tutte le informazioni della dipendenza (cioè nell’interfaccia) nel caso in cui l’accoppiamento stretto ti dia direttamente la dipendenza che non è un buon modo di codificare.

Riguarda il tasso di dipendenza delle classi da un altro, che è così basso in modo scarsamente accoppiato e così in alto strettamente accoppiato. Per essere chiari nell’architettura dell’orientamento al servizio , i servizi sono reciprocamente accoppiati l’uno contro l’ altro contro il monolitico che le dipendenze delle classi sono reciprocamente apposte

Tight Coupling significa che una class dipende da un’altra class. Loose Coupling significa che una class dipende dall’interfaccia rathar che dalla class.

Nell’accoppiamento stretto, esiste una dipendenza hardcoded dichiarata nei metodi. Nell’accoppiamento Loose, è necessario passare la dipendenza esternamente in fase di esecuzione anziché in modalità hardcoded. (I sistemi a coppia libera utilizzano l’interfaccia per diminuire la dipendenza con la class)

Ad esempio, abbiamo un sistema che può inviare l’output in due o più modi, come JSON-Output, CSV-Output, ecc.

Stretto accoppiato

 public interface OutputGenerator { public void generateOutput(); } public class CSVOutputGenerator implements OutputGenerator { public void generateOutput() { System.out.println("CSV Output Generator"); } } public class JSONOutputGenerator implements OutputGenerator { public void generateOutput() { System.out.println("JSON Output Generator"); } } // In Other Code, we write Output Generator like... public class Class1 { public void generateOutput() { // Here Output will be in CSV-Format, because of hard-coded code. // This method tightly coupled with CSVOutputGenerator class, if we want another Output, we must change this method. // Any method, that calls Class1's generateOutput will return CSVOutput, because Class1 is tight couple with CSVOutputGenerator. OutputGenerator outputGenerator = new CSVOutputGenerator(); output.generateOutput(); } } 

Nell’esempio precedente, se vogliamo modificare l’output in JSON, dobbiamo trovare e modificare l’intero codice, perché Class1 è strettamente accoppiato con la class CSVOutputGenerator.

Sciolto accoppiato

 public interface OutputGenerator { public void generateOutput(); } public class CSVOutputGenerator implements OutputGenerator { public void generateOutput() { System.out.println("CSV Output Generator"); } } public class JSONOutputGenerator implements OutputGenerator { public void generateOutput() { System.out.println("JSON Output Generator"); } } // In Other Code, we write Output Generator like... public class Class1 { public void generateOutput(OutputGenerator outputGenerator) { // if you want to write JSON, pass object of JSONOutputGenerator (Dependency will be passed externally to this method) // if you want to write CSV, pass object of CSVOutputGenerator (Dependency will be passed externally to this method) // Due to loose couple with class, we don't need to change code of Class1, because Class1 is loose coupled with CSVOutputGenerator or JSONOutputGenerator class // Any method, that calls Class1's generateOutput will desired output, because Class1 does not tight couple with CSVOutputGenerator or JSONOutputGenerator class OutputGenerator outputGenerator = outputGenerator; output.generateOutput(); } } 

Se la creazione / esistenza di un object dipende da un altro object che non può essere adattato, il suo accoppiamento stretto. E, se la dipendenza può essere adattata, il suo accoppiamento lento. Considera un esempio in Java:

 class Car { private Engine engine = new Engine( "X_COMPANY" ); // this car is being created with "X_COMPANY" engine // Other parts public Car() { // implemenation } } 

Il cliente della class Car può crearne uno con SOLO il motore “X_COMPANY”.

Prendi in considerazione la possibilità di rompere questo accoppiamento con la possibilità di cambiarlo:

 class Car { private Engine engine; // Other members public Car( Engine engine ) { // this car can be created with any Engine type this.engine = engine; } } 

Ora, una Car non dipende da un motore di “X_COMPANY” in quanto può essere creato con i tipi.

Una nota specifica di Java: l’ utilizzo di interfacce Java solo per l’eliminazione del sake non è un approccio appropriato. In Java, un’interfaccia ha uno scopo: agire come un contratto che fornisce intrisically comportamento / vantaggio di disaccoppiamento.

Il commento di Bill Rosmus nella risposta accettata ha una buona spiegazione.