L'SRP alimenta l'accoppiamento stretto?

2

Ho progettato una funzione che, in seguito, ho notato che sta facendo chiaramente 2 compiti molto diversi nello stesso tempo.

Quindi ora sto pensando di dividerlo in 2 diverse funzioni, ognuna delle quali fa solo ciò che dovrebbe fare ( SRP ). Ovviamente, una di queste funzioni chiamerà i servizi dell'altro.

Ma mi chiedo se questa sia davvero una buona decisione perché tendo a pensare che questa chiamata aumenti l'accoppiamento stretto come da questo (?)

Quindi la mia domanda è: SRP aumenta l'accoppiamento stretto?

    
posta Billal Begueradj 25.08.2018 - 07:55
fonte

3 risposte

4

SRP si applica a classi e moduli:

C'è molta confusione su SRP. Qui un articolo di Uncle Bob , che " ha inventato "SRP, che lo spiega molto meglio di quanto potrei. In breve:

  • SRP non riguarda ciò che fa la classe (la responsabilità della classe). Quindi non ti obbliga ad abbattere le classi in gemelli strettamente accoppiati solo perché eseguiranno diverse cose.

  • SRP è la ragione per cambiare (la responsabilità per la classe). Incoraggia l'incapsulamento e facilita il principio della minima conoscenza, che combinata dovrebbe portare ad un minore accoppiamento.

Le funzioni dovrebbero fare una cosa?

Il suo libro Pulisci codice , Uncle Bob consiglia le funzioni all'interno di una classe o un modulo " Fai uno cosa ". Può sembrare un SRP ma è qualcosa di molto diverso. Insieme a " Keep it Small " e " Un livello di astrazione per funzione ", promuove una corretta scomposizione funzionale in parti più piccole che sono più facili da comprendere e mantenere.

Ovviamente, una funzione dipenderà dalle sottofunzioni che sono state create per scomporla. All'interno della stessa classe, l'accoppiamento è inevitabile. Ma questo non è un problema finché non esponi questi dettagli interni al mondo esterno.

    
risposta data 25.08.2018 - 10:01
fonte
3

Uno dei principali vantaggi del basso accoppiamento è che riduce il numero di cose da considerare simultaneamente per comprendere un singolo componente di un sistema, consentendo tra l'altro di semplificare il debugging, semplificare la manutenzione e migliorare l'estendibilità. Un modo ragionevole per rispondere alla tua domanda è considerare se SRP possa migliorare il tuo codice rispetto a questi parametri.

La mia affermazione è che SRP ha la capacità di ridurre l'accoppiamento , ma che l'accoppiamento ridotto non è garantito. Illustrerò questo con due scenari.

Scenario 1 (non farlo)

  • Inizia con una mega funzione foo() .
  • Tieni presente che foo() viola SRP, quindi ridimensionalo in bar() e baz() .
  • Man mano che la tua applicazione cresce, altre parti del codice finiscono a seconda di bar() e baz() .
  • I clienti e i casi d'uso cambiano nel tempo, quindi alla fine foo() ha bisogno di una modifica. La maggior parte della logica in foo() è implementata in bar() e baz() , quindi per cambiare comportamento in foo() cambiamo il comportamento in bar() e baz() invece .
  • Ora tutto si rompe.

Anche se SRP ha la capacità di ridurre l'accoppiamento (almeno lo sto affermando), in questo esempio il programmatore sta trattando foo() , bar() e baz() come una singola unità E hanno il complessità aggiuntiva di tale unità che viene suddivisa tra più definizioni di funzioni e forse anche più file. L'SRP era solo di nome e non aveva reali vantaggi a causa del modo in cui venivano utilizzate le funzioni.

Scenario 2 (accoppiamento ridotto con SRP)

  • Inizia con una mega funzione foo() .
  • Tieni presente che foo() viola SRP, quindi ridimensiona in bar() e baz() .
  • Man mano che la tua applicazione cresce, altre parti del codice finiscono a seconda di bar() e baz() .
  • Alla fine foo() ha bisogno di una modifica, ma non abbiamo un componente di basso livello appropriato in giro con la funzionalità desiderata, quindi facciamo una nuova funzione bizz() .
  • Ora foo() è composto da bar() e bizz() , e tutto il resto funziona ancora.

In questo esempio, è facile ragionare sul comportamento di foo() perché trattiamo le sue due parti costitutive come atomico . Hanno un comportamento ben definito e combinati costituiscono foo() . Quando tali comportamenti sono insufficienti, creiamo un nuovo componente atomico con la funzionalità desiderata. Questo approccio porta facilmente al riutilizzo del codice e impedisce modifiche all'API. Inoltre, tutti i componenti sono abbastanza piccoli e possono essere facilmente ragionati e dimostrati come corretti.

Extra: Anche se SRP può ridurre l'accoppiamento in un certo senso, se le funzioni non sono raggruppate in modo appropriato, ha la possibilità di avere ogni modulo in un'applicazione in un modo o nell'altro in ogni altro modulo. La progettazione dell'intero sistema da accoppiare liberamente è tanto importante quanto la progettazione di funzioni da accoppiare liberamente, e per approssimativamente le stesse ragioni.

    
risposta data 25.08.2018 - 10:12
fonte
3

Da qualsiasi punto di vista ragionevole, l'azione di estrazione di parte di funzione in un'altra funzione non causa alcun danno che possa essere attribuito a un accoppiamento. Ciò che può essere negativo è che più tardi qualcuno riutilizza le funzioni estratte senza un'attenta considerazione è davvero la stessa funzionalità (come nello scenario descritto in un'altra risposta). Pertanto, dovresti considerarlo attentamente e limitare l'utilizzo delle sottofunzioni, utilizzando le misure fornite dalla tua lingua (metodi privati, ecc.)

    
risposta data 25.08.2018 - 15:26
fonte