Come e applicare correttamente il principio della singola responsabilità? [duplicare]

1

Da Wikipedia su Principio di responsabilità singola SoC

... class should have responsibility over a single part of the functionality provided by the software, and that responsibility should be entirely encapsulated by the class. All its services should be narrowly aligned with that responsibility

class or module should have one, and only one, responsibility . As an example, consider a module that compiles and prints a report. Imagine such a module can be changed for two reasons. First, the content of the report could change. Second, the format of the report could change. These two things change for very different causes; one substantive, and one cosmetic. The single responsibility principle says that these two aspects of the problem are really two separate responsibilities, and should therefore be in separate classes or modules. It would be a bad design to couple two things that change for different reasons at different times.

The reason it is important to keep a class focused on a single concern is that it makes the class more robust. Continuing with the foregoing example, if there is a change to the report compilation process, there is greater danger that the printing code will break if it is part of the same class.

Esiste una regola o una linea guida generale su come definire la responsabilità dei metodi in classe?

Quando parliamo di oggetti inanimati, è facile vedere il report di compilazione e il rapporto di stampa sono due diverse responsabilità. Tuttavia, quando si tratta di animare oggetti come il cane, diventa meno evidente quali metodi siano diversi in natura.

Supponiamo di avere:

class dog {
   public $breed;
   public $age;
   public $color;

   function bark($loudness) (
      ...
   ) 

   function pee($amount) (
      ...
   ) 

   function run($speed, $distance, $direction) (
      ...
   ) 

   function growl() (
      ...
   ) 

   function drink() (
      ...
   ) 
} 

come puoi dire quale responsabilità dovrebbe essere in una classe separata?

    
posta Roman Toasov 02.11.2016 - 22:38
fonte

3 risposte

3

Generale

La singola responsabilità ha qualcosa da dire sulla ridondanza semantica e sulla falsa coesione semantica dei frammenti di codice (moduli, classi, funzioni dei metodi). Il problema è (con tutti i principi SOLID) non si tratta di applicarli, si tratta di identificare loro una violazione . Una volta che ritieni che violi l'SRP, puoi fare un esperimento mentale (coordinato con i tuoi uomini d'affari) che il tuo codice deve passare per verificare la tua ipotesi.

Ridondanza semantica

Se si verifica un requisito funzionale e devi cambiare due frammenti di codice per lo stesso motivo per cui violi l'SRP.

Questo accade spesso se uno sviluppatore non sa che esiste già una logica che risolverà un problema per lui e lo svilupperà ancora una volta.

False coesione semantica

Se si verifica un requisito funzionale e si produce un effetto collaterale involontario in un altro frammento di codice, si viola lo SRP.

Questo accade se gli sviluppatori tecnicamente esperti cercano di ridurre la duplicazione del codice senza considerare la semantica.

es. un controllo di parte locale per un indirizzo di posta elettronica è stato implementato in diverse posizioni del tuo codice base. Uno sviluppatore estrae il codice in un metodo centrale perché sembra tecnicamente uguale. Un'altra volta un altro sviluppatore deve modificare il controllo della parte locale per un caso e non controlla se tutti gli altri usi saranno corretti nella nuova implementazione.

Conclusione

Il codice duplicato può essere un motivo per pensare alla violazione SRP. Ma devi stare attento se metti insieme il codice che sembra essere uguale. Non puoi sfuggire alla semantica. Devi identificare cosa significa realmente il codice nel contesto per decidere se c'è una violazione di SRP.

Puoi suddividerlo in: Devi mettere insieme le cose che appartengono insieme e devi isolare le cose che non appartengono insieme. Ma questo è un processo di identificazione.

Nel tuo esempio hai una classe Dog con diversi metodi che rappresentano le azioni di un cane. Se sei paranoico puoi vedere le tue prime ridondanze: tutti i metodi possono essere "eseguiti". Quindi "Esecuzione" è ciò che tutti hanno in comune. Ma abbiamo difficoltà a estrarre questa parte dal momento che il linguaggio di programmazione si prende cura dell'esecuzione. Quindi ci sono limiti inferiori a SRP relativi al linguaggio di programmazione utilizzato.

Ok. Il tuo cane abbaia, fa pipì, beve, ringhia e corre. Posso solo dire che al momento non vedo alcuna violazione di SRP. Ma questo non significa che non ci sia. Una volta trovato un indicatore che può essere semanticamente ridondante o falso nel contesto della coesione semantica, puoi accenderlo.

Dopotutto voglio dire che a volte alcune violazioni SRP possono essere tollerate poiché il codice dovrebbe essere stabile nelle modifiche. Ma questo è solo per essere pragmatico e mai una regola.

    
risposta data 03.11.2016 - 00:20
fonte
11

La responsabilità qui è dog . Il cane è come un cane.

Molte persone leggono il Principio di Responsabilità Unica come "Deve fare solo una cosa". Questo non è ciò che significa. Bob Martin, autore del principio (e fonte prolifica di confusione di massa per programmatori inesperti ovunque) lo dice così:

Every class should have only one reason to change.

Vedo una classe come incarnazione di uno "scopo" o "area di responsabilità". Se scrivi una classe che contiene i metodi Create , Read , Update e Delete , quelle non sono quattro responsabilità; sono solo uno: Accesso ai dati

    
risposta data 02.11.2016 - 22:49
fonte
1

I questa conferenza in Yale, Uncle Bob fornisce questo divertente esempio:

DicecheEmployeehatremotivipercambiare,trefontidirequisitidimodificaeforniscequestaumoristica,ironica,,macomunqueillustrativa,spiegazione:

  • IftheCalcPay()methodhasanerrorandcoststhecompanymillionsofUS$,theCFOwillfireyou.

  • IftheReportHours()methodhasanerrorandcoststhecompanymillionsofUS$,theCOOwillfireyou.

  • IftheWriteEmmployee()methodhasanerrorthatcausestheerasureofalotofdataandcoststhecompanymillionsofUS$,theCTOwillfireyou.

SohavingthreedifferentClevelexecspotentiallyfiringyouforcostlyerrorsinthethesameclassmeanstheclasshastoomanyresponsabilities.

ForniscequestasoluzionecherisolvelaviolazionediSRP,madeveancoraapplicareilDIP(DependencyInversionPrinciple)chespiegamanonvienemostratonelvideoperchénonc'ènessunaimmaginedellatelecameranelladiapositivamentrelofa.

    
risposta data 03.11.2016 - 13:31
fonte

Leggi altre domande sui tag