Quando l'accoppiamento Efferente / Afferente è buono o cattivo


11

Questa settimana ho un esame dei modelli software e uno degli argomenti che dobbiamo studiare è l'accoppiamento Efferente e Afferente.

Capisco che un pacchetto ha un elevato Ce (accoppiamento efferente) se dipende da un numero di altri tipi.

Per esempio:

class Car{
    Engine engine;
    Wheel wheel;
    Body body;
}

Questa classe avrebbe un accoppiamento efficiente perché dipende dal tipo di motore, ruota e carrozzeria.

Considerando che il tipo "Ruota" avrebbe un elevato Ca (accoppiamento afferente) se diversi altri pacchetti dipendessero da esso (Auto, Aereo, Bicicletta).

Una delle possibili domande sul nostro esame è: quando l'accoppiamento Efferente / Afferente è buono o cattivo? Mi sembra strano perché logicamente un programma avrebbe bisogno di pacchetti / classi con accoppiamento sia Efferent / Afferent elevato.

Qualcuno ha un esempio di quando / dove l'accoppiamento efferente o afferente è buono / cattivo ??

Grazie !


4
Se solo avessero scelto termini più confusi che suonavano ancora più simili ...
user949300 il

Risposte:


11

L'accoppiamento afferente può essere facilmente valutato in termini di quantità di dolore che causa / salva a causa della necessità di cambiamento o della probabilità. Ad esempio, prendi la tua classe di ruote e diciamo che molti altri moduli lo usano per costruire vari tipi di veicoli. Se la classe di ruote è estremamente stabile, questo accoppiamento afferente è vantaggioso poiché i veicoli hanno bisogno di ruote e ne usano una affidabile. Se, d'altra parte, la classe delle ruote è volatile in termini di manutenzione, questo accoppiamento afferente sarà un punto dolente quando si introducono ripetutamente le modifiche di rottura a un sacco di codice.

L'accoppiamento efficace è simile nel concetto, ma vedrai una proposta di valore leggermente diversa. Se hai una classe di auto che dipende direttamente da molte parti singole (al contrario di solo "Motore" e "Telaio", e sono costituite da altre parti secondarie), la classe probabilmente fa molto e può quindi essere un collo di bottiglia di manutenzione. Le modifiche a quella classe sono probabilmente difficili e rischiose a causa della sua complessità. D'altra parte, se l'accoppiamento efferente è elevato, ma in realtà è piuttosto coerente e chiaro, allora non hai una gerarchia di oggetti e relazioni di cui preoccuparti.

Quando si tratta di architettura / design, ciò che devi davvero considerare sono praticamente infiniti compromessi e queste metriche non sono diverse. Se vuoi capire un esempio di qualcosa di buono o cattivo, gioca al gioco "what if". Immagina un esempio e dì "E se volessi fare X - quanto sarebbe schifo?" Per X in cui la risposta è "molto", hai uno svantaggio e per X in cui la risposta è "che in realtà sarebbe davvero facile" hai un vantaggio.


5

Parlando in generale, accoppiamento libero:

positivo : protegge una parte del sistema dai cambiamenti in qualcosa da cui dipende (accoppiamento afferente)

negativo : la relazione potrebbe essere più difficile da capire

Ad esempio, se stavo sviluppando un sistema che si basava su HTTTP, deciderei se devo accoppiare strettamente o liberamente a HTTP. Se pensassi che il sistema probabilmente passerà a un protocollo diverso, potrei scegliere di accoppiarlo liberamente, mentre se accettassi che HTTP fosse il mio protocollo, potrei accoppiarlo strettamente a quel protocollo per semplicità nella comprensione.

Considera che alcune delle complessità in WS * sono nel suo disaccoppiamento da HTTP come protocollo.


Risposta intelligente, ma non vedo come sia correlato alla domanda, che riguardava l'accoppiamento efferente / afferente e non l'accoppiamento stretto / allentato.
lbalazscs,

Hai ragione, @lbalazscs. Non ho idea del perché ho risposto senza rispondere alla domanda!
Jayraynet,

1

afferente

Se qualcosa usa un sacco di cose diverse (alto numero di accoppiamenti afferenti), allora potrebbe essere incline a rompersi se una di queste cose cambia.

Instabilità = 1

inserisci qui la descrizione dell'immagine

efferente

Se qualcosa viene utilizzato da un sacco di cose diverse (elevato numero di accoppiamenti efferenti), allora potrebbe essere incline a rompere un sacco di cose se cambia.

Instabilità = 0

inserisci qui la descrizione dell'immagine

Stabilità

La definizione di "stabilità" di Martin è una miscela esotica tra "difficile da cambiare" e "avere poche ragioni per cambiare". Tuttavia la sua metrica di instabilità descrive solo "difficoltà di cambiamento". I "motivi per cambiare" avranno molto più a che fare con fattori che non possono essere facilmente calcolati, come la semplice progettazione delle interfacce in modo appropriato, a un livello adeguato di astrazione e la comprensione più chiara dei requisiti dell'utente finale.

Quindi un accoppiamento efferente elevato con un accoppiamento afferente basso fornisce stabilità (come in qualcosa di difficile da cambiare poiché romperà un mucchio di cose), il contrario produce instabilità (come in qualcosa di facile da cambiare poiché non romperà un mucchio di roba) .

Un gran numero di accoppiamenti afferenti potrebbe essere un indicatore del fatto che il tuo progetto non è focalizzato - sta usando un sacco di cose diverse, quindi forse manca di una responsabilità chiara e singolare.

Un gran numero di accoppiamenti efferenti potrebbe inizialmente essere interpretato come una cosa davvero buona, in quanto indica che il tuo progetto viene ampiamente riutilizzato. Eppure sarebbe male se ti senti tentato di cambiare il design spesso in modo da rompere tutto. Quindi con un gran numero di accoppiamenti efferenti arriva la necessità che tali pacchetti abbiano "poche o nessuna ragione per cambiare". I progetti dovrebbero essere stabili nel senso ideale di non avere ragioni per cambiare, poiché allo stesso modo saranno molto difficili da cambiare.

Principio di astrazioni stabili

Concetti come l'inversione delle dipendenze (che naturalmente richiede l'iniezione delle dipendenze) e SAP (principio delle astrazioni stabili) suggeriscono che le dipendenze fluiscono verso le astrazioni. E c'è una semplice ragione per cui quando si considera la "stabilità" nel contesto di "poche ragioni per cambiare". Un'interfaccia astratta non menziona dettagli concreti, si concentra solo su "cosa fare" invece di "cosa sono le cose" e quindi ha meno ragioni per cambiare. La porta grafica accelerata sulle nostre schede madri (interfaccia astratta) ha meno motivi per subire una modifica di progettazione rispetto alla GPU che si inserisce (un dettaglio concreto).

Riutilizzabilità vs. riutilizzo

Un mio tipo personale di metrica se posso suggerirne uno che si scontra in qualche modo con quello di Martin è questa idea che mi piace spingere che le biblioteche più riutilizzabili dovrebbero cercare di riutilizzare minimamente altri codici. Ciò spinge l'instabilità verso un livello 0. È per ragioni pratiche di avere ragioni minime per cambiare, ma anche per promuovere la libreria più semplice da distribuire. Una libreria per scopi generici e ampiamente utilizzata che dipende da una dozzina di librerie diverse ha molte ragioni per cambiare, così come una distribuzione raggruppata in modo scomodo che può essere difficile da distribuire. La differenza qui è che i "motivi per cambiare" nel mio caso si estendono anche all'implementazione, poiché proviene da una visione orientata alla libreria che cerca di rilasciare versioni stabili della libreria. Martin potrebbe scartare l'implementazione come parte molto separata,

Dal punto di vista della distribuzione, l'implementazione e l'interfaccia si confondono per produrre dipendenze dell'utente in una libreria stabile o instabile. Dal punto di vista dell'interfaccia, viene utilizzata solo l'interfaccia e i dettagli di implementazione associati sono completamente separati.

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.