Che cos'è il disaccoppiamento e a quali aree di sviluppo può applicare? [chiuso]


21

Di recente ho notato il disaccoppiamento come argomento in una domanda e voglio sapere di cosa si tratta e dove può essere applicato.

Per "dove può applicarsi", intendo:

È rilevante solo quando sono coinvolti linguaggi compilati come C e Java?

Dovrei saperlo / studiarlo come sviluppatore web?


Sarebbe utile se facessi una piccola ricerca e ponessi una domanda in base a parti poco chiare della definizione.
JeffO,

2
@JeffO - Penso che il mondo tragga beneficio da domande concettuali complete quanto da sfumature specifiche. "Perchè il cielo è blu?" consente alle risposte di coprire il concetto stesso senza entrare nei dettagli estremi sui dettagli. Ecco perché sono andato avanti e ho posto la mia domanda senza ricerche.

Qual è il problema specifico che stai riscontrando? Allo stato attuale, la tua domanda è molto troppo ampia. Nella forma attuale, la risposta è essenzialmente l'intero testo di Structured Design: Fundamentals of a Discipline of Computer Program and Systems Design di Edward Yourdon e Larry Constantine .
Jörg W Mittag,

Penso che le risposte qui facciano un lavoro perfetto nel descrivere il concetto. È come chiedere "Qual è la definizione di questa parola in relazione alla programmazione" - Come mai è troppo ampia? @ GlenH7

1
@ jt0dd Dovrei essere d'accordo. Solo perché puoi spiegare qualcosa con un libro, non significa che non ci sia valore in una risposta più concisa. Con la letteratura di programmazione, le persone spesso ti invadono con i dettagli prima di dare una panoramica decente di livello superiore. "Che cos'è OOP?" sarebbe troppo ampio. Ma questo è un argomento IMO ragionevolmente specifico.
Erik Reppen,

Risposte:


57

"Accoppiamento" è un termine che descrive la relazione tra due entità in un sistema software (in genere le classi).

Quando una classe utilizza un'altra classe o comunica con essa, si dice che "dipende" da quell'altra classe, e quindi queste classi vengono "accoppiate". Almeno uno di loro "sa" dell'altro.

L'idea è che dovremmo cercare di mantenere l'accoppiamento tra le classi nei nostri sistemi il più "allentato" possibile: quindi "accoppiamento lento" o talvolta "disaccoppiamento" (sebbene in inglese "disaccoppiamento" significherebbe "nessun accoppiamento", le persone spesso lo usano per implicare un "accoppiamento lento" tra entità).

Quindi: in che cosa consiste l'accoppiamento libero rispetto all'accoppiamento forte in pratica, e perché dovremmo creare entità liberamente accoppiate?


L'accoppiamento descrive il grado di dipendenza tra un'entità e un'altra entità. Spesso classi o oggetti.

Quando ClassA dipende fortemente da ClassB, le possibilità che ClassA venga influenzata quando si cambia ClassB sono elevate. Questo è un accoppiamento forte.

Tuttavia, se la Classe A dipende leggermente dalla Classe B, le possibilità che la Classe A subisca in qualche modo una modifica del codice della Classe B sono basse. Questo è un accoppiamento libero o una relazione "disaccoppiata".

L'accoppiamento lento è buono perché non vogliamo che i componenti del nostro sistema dipendano fortemente l'uno dall'altro. Vogliamo mantenere il nostro sistema modulare, in cui possiamo cambiare in sicurezza una parte senza influire sull'altra.

Quando due parti sono accoppiate liberamente, sono più indipendenti l'una dall'altra e hanno meno probabilità di rompersi quando le altre cambiano.

Ad esempio, quando si costruisce un'auto, non si vorrebbe un cambiamento interno nel motore per rompere qualcosa nel volante.

Mentre questo non accadrà mai per caso durante la costruzione di un'auto, cose simili accadono continuamente ai programmatori. L'accoppiamento lento ha lo scopo di ridurre il rischio che ciò accada.

Il forte accoppiamento di solito si verifica quando l'entità A sa troppo sull'entità B. Se l'entità A fa troppe ipotesi su come opera l'entità B o su come è costruita, allora c'è un rischio elevato che una variazione nell'entità B influenzerà l'entità A. Questo è perché uno dei suoi presupposti sull'entità B ora è errato.

Ad esempio, immagina che come guidatore faresti alcune ipotesi su come funziona il motore della tua auto.

Il giorno in cui acquisti una nuova auto con un motore che funziona in modo diverso (o per qualche ragione il tuo motore è stato sostituito), i tuoi presupposti precedenti sarebbero errati. Se tu fossi il codice in un computer, ora potresti essere un codice errato che non funziona correttamente.

Tuttavia, se tutte le ipotesi che come guidatore hai fatto sulle auto è che: A- hanno i volanti e B- hanno i pedali del freno e del gas, che i cambiamenti nell'auto non ti influenzeranno, purché le tue poche assunzioni rimani corretto. Questo è un accoppiamento lento.


Una tecnica importante per ottenere un accoppiamento lento è l'incapsulamento. L'idea è che una classe nasconda i suoi dettagli interni da altre classi e offre un'interfaccia rigorosamente definita per consentire ad altre classi di comunicare con essa.

Così, per esempio, se si definisce una classe Car, la sua interfaccia (metodi pubblici) probabilmente sarebbe drive(), stop(), steerLeft(), steerRight(), getSpeed(). Questi sono i metodi che altri oggetti possono invocare sugli oggetti Car.

Tutti gli altri dettagli della classe Car: come funziona il motore, il tipo di carburante che utilizza, ecc. Sono nascosti ad altre classi - per impedire loro di sapere troppo sulla Car.

Nel momento in cui la classe A sa troppo della classe B: abbiamo una relazione fortemente accoppiata, in cui la classe A è troppo dipendente dalla classe B e un cambiamento nella classe B potrebbe influire sulla classe A. Rendere il sistema difficile da espandere e mantenere.

Una relazione tra due entità, in cui si conoscono poco (solo ciò che è necessario) - è una relazione liberamente accoppiata o disaccoppiata.


3

Il disaccoppiamento consiste generalmente nel vedere se due cose devono o meno lavorare in stretta collaborazione o possono essere ulteriormente rese indipendenti. L'indipendenza è fantastica perché rende queste cose facili da cambiare o usare altrove. Il disaccoppiamento può essere applicato in molte aree, non solo nello sviluppo, e questo è particolarmente vero per il disaccoppiamento temporale, che può anche essere applicato nella tua vita quotidiana (in una certa misura). Inoltre, ci sono molti tipi di accoppiamento nello sviluppo del software da considerare, e non tutti saranno trattati nella risposta. Dovrai fare le tue ricerche.

Due cose, A e B , sono accoppiate se c'è una dipendenza tra di loro. Se A dipende da B, puoi usare B senza considerare A. Se vuoi usare A, dovrai portare anche B, poiché A dipende da questo.

Nello sviluppo del software, di solito, non è possibile rimuovere completamente l'accoppiamento tra i componenti. Il disaccoppiamento in quel contesto normalmente significa allentare l'accoppiamento esistente. Cioè, assicurandosi che ogni componente sappia il meno possibile sugli altri componenti che lo circondano.

Questo è probabilmente il tipo più comune di accoppiamento trovato in natura:

//Inside a class meant to display info for a particular Facebook user.
void DisplayFriends(FacebookUser user, FacebookClient client)
{
     Friend[] = (Friend[])client.GetConnection().ExecuteCommandForResult("getFriends:" + user.Name);
     ...
}

Qui DisplayFriends funziona inutilmente manualmente con la connessione dietro il client di Facebook per ottenere ciò di cui ha bisogno. DisplayFriendsLa classe è accoppiata ad entrambi FacebookCliente Connection. Se FacebookClient cambia improvvisamente il tipo di connessione che utilizza, l'app non sarà più in grado di ottenere gli amici di Facebook. Possiamo rimuovere l'accoppiamento tra la classe DisplayFriends e Connection chiedendo a FacebookClient di fornire ciò di cui abbiamo bisogno per noi.

//Inside a class meant to display info for a particular Facebook user.
void DisplayFriends(FacebookUser user, FacebookClient client)
{
     Friend[] = client.GetFriends(user);
     ...
}

Ora non ci interessa davvero come FacebookClient attiri i nostri amici. Tutto ciò che ci interessa davvero è il fatto che li ottenga. Qualsiasi modifica apportata al suo comportamento interno non danneggerà la nostra stessa classe.

Questo tipo di disaccoppiamento può essere facilmente raggiunto seguendo la Legge di Demetra per le funzioni, che dice (citando Wikipedia):

La Legge di Demetra per le funzioni richiede che un metodo m di un oggetto O possa invocare solo i metodi dei seguenti tipi di oggetti:

  • O stesso
  • parametri di m
  • Qualsiasi oggetto creato / istanziato entro m
  • Oggetti componenti diretti di O.
  • Una variabile globale, accessibile da O, nell'ambito di m

Da quando ho parlato dell'accoppiamento temporale all'inizio della risposta, lo descriverò brevemente.

L'accoppiamento temporale viene normalmente considerato quando si progettano applicazioni che eseguono algoritmi in parallelo. Considera due unità eseguibili (siano esse istruzioni, metodi o qualunque cosa tu voglia considerare un'unità), A e B. Diciamo che A è temporalmente accoppiato a B se B deve essere eseguito prima che A venga eseguito. Se A non è accoppiato temporalmente a B, A e B possono essere eseguiti contemporaneamente. Crea il tuo esempio per questo: pensa alle solite cose che fai nella tua vita quotidiana. Ci sono due cose che fai una dopo l'altra, ma potresti fare allo stesso tempo?

Infine, per rispondere al tuo ultimo bit:

Dovrei saperlo / studiarlo come sviluppatore web?

Sì. Ad esempio, uno dei modelli di progettazione più popolari per lo sviluppo web (MVC) riguarda il disaccoppiamento.


1

Le altre risposte fanno un buon lavoro nel descrivere cos'è il disaccoppiamento. Volevo discutere la tua ultima domanda.

Dovrei saperlo / studiarlo come sviluppatore web?

La risposta è un enfatico sì. Non importa che tipo di sviluppatore sei. Potresti essere uno sviluppatore web o uno sviluppatore di sistemi integrati.

Supponiamo che tu abbia una classe che genera URL personalizzati che vengono inseriti nella tua pagina web. Potresti essere tentato di fare in modo che la classe scriva gli URL direttamente sulla pagina, mettendoli nel mezzo di un tag. All'inizio questo potrebbe sembrare più semplice. Ma cosa succede quando è necessario apportare una modifica per inserire i collegamenti in un'e-mail e inviarli a un utente? Il tuo codice attuale non funzionerebbe perché il tuo generatore di URL è strettamente accoppiato al framework web che stai utilizzando.

L'opzione migliore sarebbe quella di avere una classe di generatore di URL che restituisca l'URL come stringa. Questo potrebbe essere usato dal tuo codice web e potrebbe anche essere usato dal tuo codice email. Potrebbe sembrare più lavoro in anticipo per avere il codice disaccoppiato, ma lo sforzo si ripaga da solo nel tempo.

Avere un codice modulare e disaccoppiato renderà il tuo codice più comprensibile, più testabile e più gestibile, indipendentemente dal dominio di programmazione in cui lavori.


Dopo questo e le altre due risposte, capisco davvero questo e vedo come posso usarlo.
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.