La singola responsabilità potrebbe non essere qualcosa che una singola funzione può svolgere.
class Location {
public int getX() {
return x;
}
public int getY() {
return y;
}
}
Questa classe può violare il principio della singola responsabilità. Non perché ha due funzioni, ma se il codice è getX()
e getY()
deve soddisfare diversi stakeholder che potrebbero richiedere cambiamenti. Se il vicepresidente Mr. X invia un promemoria secondo cui tutti i numeri devono essere espressi come numeri in virgola mobile e il direttore contabile, la signora Y, insiste sul fatto che tutti i numeri che le sue recensioni di reparto devono rimanere numeri interi, indipendentemente da ciò che il signor X pensa bene, quindi questa classe dovrebbe avere una singola idea di chi è responsabile perché le cose stanno per diventare confuse.
Se fosse stato seguito SRP, sarebbe chiaro se la classe Location contribuisse alle cose a cui il sig. X e il suo gruppo sono esposti. Chiarisci di cosa è responsabile la classe e sai quale direttiva ha un impatto su questa classe. Se hanno entrambi un impatto su questa classe, allora è stata progettata male per minimizzare l'impatto del cambiamento. "Una classe dovrebbe avere solo un motivo per cambiare" non significa che l'intera classe possa fare solo una piccola cosa. Significa che non dovrei essere in grado di guardare la classe e dire che sia il signor X che la signora Y hanno interesse per questa classe.
A parte cose del genere. No, più metodi vanno bene. Dagli semplicemente un nome che chiarisca quali metodi appartengono alla classe e quali no.
L'SRP di zio Bob riguarda più la legge di Conway che la legge di Curly . Lo zio Bob sostiene l'applicazione della legge di Curly (fai una cosa) a funzioni e non a classi. SRP mette in guardia contro il mescolare le ragioni per cambiare insieme. La legge di Conway afferma che il sistema seguirà il modo in cui scorre l'informazione di un'organizzazione. Ciò porta a seguire SRP perché non ti importa di ciò di cui non hai mai sentito parlare.
"Un modulo dovrebbe essere responsabile nei confronti di un solo attore"
Robert C Martin - Architettura pulita
Le persone continuano a desiderare che SRP riguardi tutti i motivi per limitare l'ambito. Esistono più motivi per limitare l'ambito rispetto a SRP. Limito ulteriormente l'ambito insistendo sul fatto che la classe è un'astrazione che può prendere un nome che assicura che guardarti dentro non ti sorprenda .
Puoi applicare la legge di Curly alle lezioni. Sei fuori da ciò di cui parla lo zio Bob, ma puoi farlo. Dove sbagli è quando inizi a pensare che significhi una funzione. È come pensare che una famiglia dovrebbe avere un solo figlio. Avere più di un figlio non gli impedisce di essere una famiglia.
Se applichi la legge di Curly a una classe, tutto nella classe dovrebbe riguardare un'unica idea unificante. Quell'idea può essere ampia. L'idea potrebbe essere la persistenza. Se alcune funzioni dell'utilità di registrazione sono presenti, sono chiaramente fuori posto. Non importa se il signor X è l'unico a cui importa questo codice.
Il principio classico da applicare qui si chiama Separazione delle preoccupazioni . Se separi tutte le tue preoccupazioni, si potrebbe sostenere che ciò che rimane in ogni posto è una preoccupazione. Questo è ciò che abbiamo chiamato questa idea prima che il film City Slickers del 1991 ci presentasse al personaggio di Curly.
Questo va bene. È solo che ciò che lo zio Bob definisce una responsabilità non è un problema. Una responsabilità nei suoi confronti non è qualcosa su cui ti concentri. È qualcosa che può costringerti a cambiare. Puoi concentrarti su una preoccupazione e creare comunque codice responsabile di diversi gruppi di persone con diversi programmi.
Forse non ti interessa. Belle. Pensare che la volontà di "fare una cosa" risolverà tutti i tuoi problemi di progettazione mostra una mancanza di immaginazione di ciò che "una cosa" può finire per essere. Un altro motivo per limitare l'ambito è l'organizzazione. Puoi annidare molte "cose" dentro altre "cose" fino a quando non avrai un cassetto spazzatura pieno di tutto. Ne ho già parlato prima
Naturalmente il classico motivo OOP per limitare l'ambito è che la classe ha campi privati al suo interno e piuttosto che usare getter per condividere quei dati, mettiamo tutti i metodi che necessitano di quei dati nella classe dove possono usare i dati in privato. Molti lo trovano troppo restrittivo per essere utilizzato come limitatore di ambito perché non tutti i metodi che appartengono insieme utilizzano esattamente gli stessi campi. Mi piace garantire che qualunque idea che abbia riunito i dati sia la stessa idea che ha riunito i metodi.
Il modo funzionale di vedere questo è quello a.f(x)
e a.g(x)
sono semplicemente f a (x) e g a (x). Non due funzioni ma un continuum di coppie di funzioni che variano insieme. Il a
non hanno nemmeno bisogno di avere i dati in esso. Potrebbe essere semplicemente il modo in cui sai quale f
e quale g
implementazione utilizzerai. Le funzioni che cambiano insieme appartengono insieme. È un buon vecchio polimorfismo.
SRP è solo uno dei tanti motivi per limitare l'ambito di applicazione. È buono. Ma non l'unico.