È una discussione su seguire molto rigorosamente l'SRP (Single Responsability Principle) vs. essere più flessibile quando si scrivono codici semplici, come l'impostazione o il recupero dei valori delle proprietà, anche fuori da un contesto diretto.
Il mio primo dubbio riguarda dove deve essere incluso SRP. Ho sempre letto che SRP dovrebbe essere applicato alle lezioni. Ma e su metodi, proprietà o tratti ( come in PHP ), ...?
Se questa risposta è no , forse possiamo eliminare tutto il testo di seguito.
Per esemplificare , definiamo un caso di esempio. Per comprendere più facilmente , scriveremo una struttura singleton per una classe chiamata Example
. Ignora IoC, in questo caso.
Dovrebbe avere due metodi, in pratica:
-
getInstance()
: restituisce un'istanza univoca della tua classe; e -
rebuildInstance()
: distruggerà solo l'istanza corrente e la ricreerà;
Fondamentalmente per il suo funzionamento, getInstance()
dovrebbe controllare se l'istanza interna è stata impostata, crearla in caso contrario, quindi restituirla. E rebuildInstance()
dovrebbe distruggere l'istanza corrente se è stata definita e creare una nuova, senza restituire nulla.
Rendiamolo più visivo ( in qualche pseudo-lingua ):
class Example
{
static private Example instance;
static public Example getInstance()
{
if (!this.instance)
{
this.instance = new Example;
}
return this.instance;
}
static public void rebuildInstance()
{
if (this.instance)
{
destroy(this.instance);
}
this.instance = new Example;
}
}
Quindi nota che:
-
getInstance()
ha due responsabilità: 1. verifica e istanzia; 2. ritorno. -
rebuildInstance()
ha due responsabilità: 1. controllare e distruggere; 2. istanziare;
Vedrai che entrambi dovrebbero creare un'istanza, quindi consideralo come una duplicazione di effetti . Per evitare ciò, dovrei disaccoppiare i miei metodi in modo che ognuno abbia una singola responsabilità, quindi ho bisogno di creare altri due metodi:
-
buildInstanceWhenNeed()
; -
destroyInstanceWhenNeed();
Diventerà più chiaro ciò che ciascun metodo fa per nome e per struttura. Quindi il nostro codice sembrerà:
class Example
{
static private Example instance;
static private void buildInstanceWhenNeed()
{
if (!this.instance)
{
this.instance = new Example;
}
}
static public Example getInstance()
{
self.buildInstanceWhenNeed();
return this.instance;
}
static private void destroyInstanceWhenNeed()
{
if (this.instance)
{
destroy(this.instance);
}
}
static public void rebuildInstance()
{
self.destroyInstanceWhenNeed();
self.buildInstanceWhenNeed();
}
}
Va bene.
Sembra che ora stia rispettando completamente l'SRP sui metodi, molto rigorosamente . Ogni metodo ha una singola responsabilità senza ottenere la responsabilità della classe. Tranne il fatto che ha un pattern singleton al suo interno, ma ho detto di ignorare l'uso di IoC all'inizio del topic.
Così ora ho altre domande:
- Devo applicare SRP ai metodi, disaccoppiandolo, per assicurarmi che abbia una singola responsabilità su ciascun metodo?
-
Se sì. Devo farlo anche quando il metodo non duplica alcun effetto? Ad esempio: se
rebuildInstance()
non esiste qui, quindi non ho bisogno di disaccoppiaregetInstance()
perché è l'istanza unica che, di fatto, creerà una nuova istanza di classe. Quindi, in questo caso, ho ancora bisogno di crearebuildInstanceWhenNeed()
o no? - Se sì, ma priorità più bassa. E a proposito delle prestazioni? Voglio dire, quando veramente influisce sul tempo di esecuzione, diminuendo considerevolmente la velocità dell'applicazione a causa dei metodi ultra disaccoppiati ( che forse interessa solo le lingue interpretate ), ma con specifiche elevate per ciascuno uno.