Un sacco di classi con un solo metodo statico con lo stesso nome della classe - Codice odore? [duplicare]

3

Sto cercando di seguire il principio di responsabilità singola (SRP) nelle mie applicazioni. Ho molte classi CRUD, mi chiamo xxxxxManager.

Seguendo l'SRP, ho creato 4 classi per ognuna:

xxxxxCreator, xxxxxGetter, xxxxxDeleter, xxxxxUpdater

Finiscono per avere un solo metodo statico: xxxxxCreator :: create (modello $ model), xxxxUpdater :: update (modello $ model), ecc.

Questo è un odore di codice per me. Sto spingendo l'SRP troppo lontano?

    
posta Lukmo 12.03.2014 - 17:21
fonte

5 risposte

14

L'unica responsabilità è l'accesso ai dati, non la creazione, la lettura, l'aggiornamento e l'eliminazione. La tua granularità è troppo piccola a quel livello.

SRP non significa che la classe dovrebbe fare solo una cosa; significa che la classe dovrebbe avere solo una ragione per cambiare. articolo di Wikipedia lo descrive come

Every class should have a single responsibility, and that responsibility should be entirely encapsulated by the class. All its services should be narrowly aligned with that responsibility.

    
risposta data 12.03.2014 - 17:31
fonte
6

Quello che stai facendo è scrivere funzioni, non classi. Non tutte le lingue consentono funzioni autonome, ma se il linguaggio ti permette, avrebbe più senso scriverle come funzioni.

Questa non è necessariamente una brutta cosa. A molte persone piace dire dogmaticamente "tutto è un oggetto", ma hanno torto: queste cose che scrivi non sono oggetti, sono funzioni, anche se indossano vestiti con oggetti. Non c'è niente di sbagliato nelle funzioni.

L'SRP è una terminologia specifica per OOP, ma l'idea funziona anche per la programmazione procedurale o funzionale; invece di un oggetto o una classe che ha una singola responsabilità, una funzione fa una sola cosa. Queste funzioni fanno una sola cosa.

Tuttavia, se Model è una classe OO o un oggetto (non solo una struttura dati che si presenta come un 'oggetto' o 'classe' nel sistema di tipi della lingua che stai usando), potrebbe non adattarsi bene con lo stile del resto del codice.

Se vuoi fare le cose in un modo più OO, suppongo che potresti inserirle nella classe Model, dal momento che i due esempi che dai entrambi prendono un modello come loro unico argomento. Quindi, supponendo che il Modello non sia già enorme, gonfio o ingombrante, sarebbe probabilmente in linea con l'SRP.

    
risposta data 12.03.2014 - 17:57
fonte
1

Non credo in nessun punto dell'SRP si dice che ogni classe dovrebbe avere un singolo metodo ... Inoltre, hai creato 4 classi che hanno molte dipendenze - le modifiche in xxxxCreator quasi certamente insieme a xxxxUpdater.

Direi che CRUD rientra sicuramente nel regno della single dependency.

    
risposta data 12.03.2014 - 17:33
fonte
1

I principi principali di responsabilità singola dell'esistenza sono:

  • Per impedirti di creare classi che fanno tutto in un caos totale e
  • Costringi a segregare il tuo codice in aspetti ben distinti.

Quindi, in sostanza, se fai una classe che gestisce le 4 azioni CRUD su un'entità, per me va bene. Inoltre, vorrei aggiungere che i tuoi metodi dovrebbero rispettare anche il principio SRP. Ad esempio, l'azione di aggiornamento NON deve restituire un'entità, è il ruolo dell'azione di lettura, non l'aggiornamento!

    
risposta data 12.03.2014 - 17:50
fonte
1

Direi di sì. Penso che ci sia stato un po 'di discussioni nel corso della giornata sulla riprogettazione di Java in modo che ogni classe avesse un solo metodo: run() . Questo è effettivamente ciò di cui stai parlando. Questo non è mai stato da nessuna parte e non ha aumentato la trazione da nessun'altra parte, perché non potevi davvero farci molto.

Ciò che si inizia a correre a questo punto è un momento molto difficile impiantare strutture di controllo molto elementari. Perché se pensi a cosa assomiglia a un'istruzione if:

if (condition)
{
    // do this
}
else
{
    // do that
}

quello sta solo facendo una cosa? È solo running() ? No, sta facendo due cose, e non è nemmeno lo stesso uno o due ogni volta. A volte doesThis() e talvolta doesThat() . Quindi quello che hai lì, con praticamente qualsiasi istruzione if con una clausola else, è una scelta:

  1. Utilizza più funzioni all'interno della classe o del modulo o altro.

  2. Utilizza solo una funzione, ma con un comportamento distinto in punti diversi che possono essere facilmente convertiti in una funzione separata.

1 pulitore è maggiore di 2 o 2 pulitore di 1? ...Sì. Dipende davvero dalla situazione, con riguardo a quale vuoi andare. Quello che non vuoi fare è sbarazzarsi delle affermazioni. E ogni ciclo non infinito che non è automaticamente interrotto implica una dichiarazione if.

Perché creare una classe separata per ogni aggiornamento, eliminazione, creazione e acquisizione? Da qualche parte lungo la strada, finirai comunque per dover fare questo:

if (condition1)
{
    xxxxxCreator.Create();
}
else if (condition2)
{
    xxxxxGetter.Get();
}
else if (condition3)
{
    xxxxxUpdater.Update();
}
else
{
    xxxxxDeleter.Delete();
}

Conto uno, due, tre, quattro cose diverse che vengono fatte tutte nella stessa classe. Anche se si suddividono in istruzioni più piccole, ci sarà comunque un condizionale da qualche parte, anche se è nel codice macchina. ... E questo viola una simile interpretazione severa della necessità di una funzione / classe che ha bisogno di fare una sola cosa.

Dato che non puoi rinunciare ai condizionali nella programmazione, non dovresti cercare di aderire a un'interpretazione così rigorosa. Vai avanti e crea una classe xxxxxManager con metodi Get() , Update() , Create() e Delete() .

    
risposta data 12.03.2014 - 17:49
fonte