Quando l'accoppiamento Efferent / Afferent è buono o cattivo

10

Ho un esame di modelli software questa settimana e uno degli argomenti che dobbiamo studiare è l'accoppiamento Efferent e Afferent.

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

Ad esempio:

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

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

Mentre il tipo "Ruota" avrebbe una Ca alta (accoppiamento afferente) se dipendesse da altri pacchetti (Car, Plane, Bicicletta).

Una delle possibili domande sul nostro esame è, quando l'accoppiamento Efferent / Afferent è buono o cattivo? Questo mi sembra strano perché logicamente un programma avrebbe bisogno di pacchetti / classi con entrambi gli accoppiamenti alti Efferent / Afferent.

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

Grazie!

    
posta TomSelleck 13.01.2013 - 22:52
fonte

3 risposte

11

L'accoppiamento afferente può essere valutato più facilmente in termini di quanto dolore provoca / risparmia a causa di necessità o probabilità di cambiamento. Ad esempio, prendi la tua lezione sulla ruota e diciamo che molti altri moduli lo usano per costruire vari tipi di veicoli. Se la classe della ruota è estremamente stabile, questo accoppiamento afferente è utile poiché i veicoli hanno bisogno di ruote e ne stanno utilizzando uno affidabile. Se, d'altra parte, la classe di ruota è volatile in termini di manutenzione, questo accoppiamento afferente sarà un punto dolente quando introdurrà ripetutamente cambiamenti di rottura in un sacco di codice.

L'accoppiamento efferente è simile nel concetto, ma tu guarderai ad una proposizione di valore leggermente diversa. Se hai una classe di auto che dipende direttamente da molte parti singole (al contrario di "Engine" e "Chassis" solo, e sono costituite da altre sotto-parti), la classe probabilmente fa molto e può quindi essere una collo di bottiglia di manutenzione. È probabile che le modifiche a quella classe siano difficili e rischiose a causa della sua complessità. D'altra parte, se l'accoppiamento efferente è alto, ma in realtà è abbastanza coeso e chiaro, non si ha una gerarchia di oggetti e relazioni di cui preoccuparsi.

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

    
risposta data 14.01.2013 - 04:04
fonte
5

Parlare in generale, accoppiamento lento:

positivo : protegge una parte del sistema dalle modifiche in qualcosa da cui dipende (accoppiamento afferent)

negativo : la relazione potrebbe essere più difficile da comprendere

Ad esempio, se sviluppassi un sistema basato su HTTTP, deciderei se devo accoppiare strettamente o liberamente con HTTP. Se pensassi che il sistema fosse in grado di passare a un protocollo diverso, potrei scegliere di accoppiarlo liberamente, mentre se accettassi che HTTP fosse il mio protocollo, potrei accoppiare strettamente quel protocollo per semplicità di comprensione.

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

    
risposta data 14.01.2013 - 01:15
fonte
1

afferenti

Se qualcosa usa un mucchio di cose diverse (numero elevato di accoppiamenti afferenti), potrebbe essere soggetto a interruzioni se qualcuno di questi cambiamenti dovesse cambiare.

Instability = 1

efferente

Sequalcosavieneusatodaunmucchiodicosediverse(altonumerodiaccoppiamentiefferenti),allorapotrebbeesseresoggettoarompereunsaccodicosesecambia.

Instability=0

Stabilità

Ladefinizionedi"stabilità" di Martin è una miscela esotica tra "difficili da cambiare" e "che hanno pochi motivi per cambiare". Eppure la sua metrica dell'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 solo la progettazione delle interfacce in modo appropriato, un livello appropriato di astrazione e la comprensione dei requisiti dell'utente più chiaramente in anticipo.

Un accoppiamento così efferente con un accoppiamento basso afferente produce stabilità (come in qualcosa di difficile da cambiare dato che rompe un mucchio di roba), l'opposto produce instabilità (come in qualcosa di facile da cambiare dato che non si spezzerà un mucchio di cose).

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

Un gran numero di accoppiamenti efferenti potrebbe inizialmente essere interpretato come una cosa veramente buona, poiché indica che il tuo progetto viene ampiamente riutilizzato. Eppure sarebbe male se ti senti tentato di cambiare il design spesso in modi che rompono tutto. Quindi, con un gran numero di accoppiamenti efferenti nasce la necessità che tali pacchetti abbiano "pochi o nessun motivo per cambiare". I progetti dovrebbero essere stabili nel senso ideale di non avere motivi per cambiare, dal momento che saranno anche molto difficili da cambiare.

Principio delle astrazioni stabili

Concetti come l'inversione di dipendenza (che naturalmente richiede l'iniezione di dipendenza) e il principio di astrazione stabile (SAP) suggeriscono che le dipendenze fluiscono verso le astrazioni. E c'è una semplice ragione per cui quando si considera la "stabilità" nel contesto di avere "pochi motivi 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 motivi per cambiare. La porta grafica accelerata delle nostre schede madri (interfaccia astratta) ha meno motivi per subire un cambiamento di progettazione rispetto alla GPU che si inserisce in esso (un dettaglio concreto).

Riutilizzabilità e riutilizzo

Un mio tipo personale di metrica, se posso suggerire quello che in qualche modo si scontra con quello di Martin, è questa idea che mi piace spingere che le librerie più riutilizzabili dovrebbero cercare di riutilizzare minimamente altro codice. Ciò spinge l'instabilità verso un hard 0. È per le ragioni pratiche di avere motivi minimi per cambiare, ma anche per promuovere la libreria più semplice da implementare. Una libreria generica e ampiamente utilizzata che dipende da una dozzina di librerie diverse ha molti motivi per cambiare, oltre a una distribuzione impacchettata che può essere difficile da implementare. La differenza qui è che "i motivi per cambiare" nel mio caso si estende anche all'implementazione, poiché proviene da una vista orientata alla libreria che cerca di rilasciare versioni stabili della libreria. Martin potrebbe scartare l'implementazione come una parte molto separata e prendere in considerazione solo le metriche associate all'interfaccia della libreria (che potrebbe essere molto più stabile della sua implementazione).

Da un punto di vista della distribuzione, l'implementazione e l'interfaccia sfocano insieme per fornire dipendenze dell'utente a 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.

    
risposta data 26.12.2015 - 02:55
fonte

Leggi altre domande sui tag