In questi giorni non trovo utile discutere di ciò che fa e non costituisce una singola responsabilità o un unico motivo per cambiare. Vorrei proporre un principio di lutto minimo al suo posto:
Principio del dolore minimo: il codice dovrebbe cercare di ridurre al minimo la probabilità di richiedere modifiche o massimizzare la facilità di modifica.
Com'è quello? Non dovrebbe prendere uno scienziato missilistico per capire perché questo può aiutare a ridurre i costi di manutenzione e speriamo che non dovrebbe essere un punto di dibattito senza fine, ma come con SOLID in generale, non è qualcosa da applicare ciecamente ovunque. È qualcosa da considerare durante il bilanciamento dei compromessi.
Per quanto riguarda la probabilità di richiedere cambiamenti, ciò si riduce con:
- Buoni test (maggiore affidabilità).
- Coinvolgere solo il codice minimo necessario per fare qualcosa di specifico (questo può includere la riduzione degli accoppiamenti afferenti).
- Basta rendere il codice tosto in quello che fa (vedi Make Badass Principle).
Per quanto riguarda la difficoltà di apportare modifiche, aumenta con gli accoppiamenti efferenti. Il test introduce giunti efficienti ma migliora l'affidabilità. Fatto bene, generalmente fa più bene che male ed è totalmente accettabile e promosso dal principio del minimo dolore.
Crea il Badass Principle: le classi che vengono utilizzate in molti luoghi dovrebbero essere fantastiche. Dovrebbero essere affidabili, efficienti se questo si lega alla loro qualità, ecc.
E il principio Make Badass è legato al principio del minimo dolore, poiché le cose toste troveranno una probabilità inferiore di richiedere cambiamenti rispetto alle cose che fanno schifo in ciò che fanno.
Avrei iniziato indicando il paradosso menzionato sopra e quindi indicando che l'SRP è fortemente dipendente dal livello di granularità che si desidera prendere in considerazione e che se lo si porta abbastanza lontano, qualsiasi classe contenente più di una proprietà o un metodo viola esso.
Dal punto di vista dell'SRP, una classe che fa a malapena qualsiasi cosa avrebbe certamente solo una (a volte zero) ragioni per cambiare:
class Float
{
public:
explicit Float(float val);
float get() const;
void set(float new_val);
};
Questo praticamente non ha motivi per cambiare! È meglio di SRP. È ZRP!
Tranne che suggerirei che è in palese violazione del principio Make Badass. È anche assolutamente inutile. Qualcosa che fa così poco non può sperare di essere tosto. Ha troppe poche informazioni (TLI). E naturalmente quando hai qualcosa che è TLI, non può fare nulla di veramente significativo, nemmeno con le informazioni che incapsula, quindi deve perderlo nel mondo esterno nella speranza che qualcun altro faccia effettivamente qualcosa di significativo e tosto. E quella perdita va bene per qualcosa che vuole solo aggregare i dati e niente di più, ma quella soglia è la differenza come vedo tra "dati" e "oggetti".
Naturalmente anche qualcosa che è TMI è male. Potremmo mettere il nostro intero software in una classe. Può anche avere solo un run
metodo. E qualcuno potrebbe persino sostenere che ora ha una ragione molto ampia per cambiare: "Questa classe dovrà essere cambiata solo se il software necessita di miglioramenti". Sono sciocco, ma ovviamente possiamo immaginarci tutti i problemi di manutenzione.
Quindi c'è un atto di bilanciamento per quanto riguarda la granularità o la ruvidezza degli oggetti che disegni. Lo giudico spesso in base a quante informazioni devi divulgare al mondo esterno e a quante funzionalità significative può svolgere. Trovo spesso utile il principio Rendi Badass per trovare l'equilibrio mentre lo combino con il principio del lutto minimo.