2012-01-10 23 views
9

Attualmente sta eseguendo una revisione del codice di materiale acquisito da un'altra squadra e ha un dubbio sull'applicazione di SRP e sulla sua relazione con il modello di dominio anemico o ricco (come definito da Martin Fowler). Il concetto di un modello di dominio ricco consiste nell'avere un oggetto intelligente che non solo possa impostare/ottenere le proprie proprietà, ma anche eseguire una logica aziendale più complessa. Mi chiedo come si inserisce in SRP?Come il principio di singola responsabilità si riferisce al modello di dominio anemico/ricco?

Dire che la mia classe modello ha alcune proprietà che possono esporre quei puntelli e fornire alcuni semplici calcoli sulle sue proprietà. requisito successivo è quello di avere la possibilità di memorizzare questi dati oggetto in un oggetto di archiviazione che non è sotto il mio controllo, in questo modo: Metodo

class MyObject { 
    // get set 
    // parse sth 

} 

Store di stoccaggio

storage.store(key, object); 

Non si viola SRP se MyObject ha un metodo store come questo

public void store(Storage storage) { 
    storage.store('keyOne', fieldOne); 
    storage.store('keyTwo', fieldTwo); 
} 

Dal punto di vista di questo oggetto è bene essere in grado di memorizzare il suo stato. altro modo potrebbe essere quello di introdurre una sorta di servizio qui e fare questo genere:

public StorageService { 
    private Storage; 
    // constructor here 
    .... 
    public void store(MyObject myobj); 
} 

Mi può indicare tutti i link che può leggere su questo problema? Ho trovato una discussione su SO qui ma non risponde alla mia domanda completamente.

Come viene risolto in DDD? I modelli in DDD sono per definizione ricchi e possono essere visti come aventi troppe responsabilità.

+3

Questa potrebbe essere un'interpretazione eccessivamente letterale di SRP. Ignora lo zio Bob e cerca la "coesione". –

+0

Come notato nella mia risposta, se l'archiviazione è stabile e astratta (ad esempio, un'interfaccia JSON, XML, RDB standard), quindi, IMO, non vi è alcun problema di coesione e inserimento nel modello di dominio. – user949300

risposta

6

Un ricco modello di dominio (RDM) significa che il logica governa comportamento del modello appartiene all'interno del modello, al contrario di trattare il modello come dati con getter/setter. Questo fa non significa che tutto ciò che include persistenza, sicurezza, come visualizzare il modello nella GUI, ecc. Deve essere all'interno del modello.

RDM e SRP vanno di pari passo, non sono in conflitto tra loro.

Violare SRP/RDM:

Car { 
    // possibly violates SRP 
    storeInDatabase(); 
    // smells like anemic domain model 
    getEngineState(); 
} 

seguito SRP/RDM:

// usings aspects to remove cross-cutting concerns from the model and follow SRP 
@DatabaseSerializable 
Car { 
    // rich domain model encapsulates engine state and exposes behavior 
    drive();    
} 
+1

Se hai un'auto con molti altri metodi oltre a Drive(), ad esempio SwitchOn(), SwitchOff(), Turn(), Brake(), PlanRoute(), hai RDM, ma non hai SRP. Più la tua classe è ricca di comportamenti, più va contro SRP. Queste sono idee opposte. –

+0

RDM indica che il modello deve contenere la logica del dominio. SRP significa che le tue classi dovrebbero essere responsabili di una cosa - nel caso del modello significa 'contenere la logica di dominio', e non contenere codice di serializzazione o codice che apre una connessione web, ecc. –

+0

Sono consapevole dei significati. JuanZe lo dice meglio: "I modelli di DDD sono per definizione ricchi e possono essere visti come aventi troppe responsabilità". In altre parole, non è facile implementare un'entità veramente ricca senza che l'entità abbia troppe responsabilità (più di 1). A meno che non si inseriscano singoli servizi/oggetti di responsabilità, nel qual caso è ADM borderline. –

4

"I modelli in DDD sono per definizione ricchi e possono essere visti come aventi troppe responsabilità" è un'interpretazione semplicistica di DDD. Dipende sempre da quanto sono buoni i tuoi modelli. È possibile creare modelli non validi utilizzando DDD (ad esempio, creando oggetti con troppe responsabilità o creando modelli anemici). DDD e SRP sono seguiti anche da due buone pratiche, oltre al refactoring, TDD e molti altri, ma dovresti integrare il loro uso con la tua esperienza e il tuo giudizio (o quello di qualcun altro). Tutto ha i suoi pro e contro, non essere dogmatico nell'applicare qualsiasi pratica.

3

@Garrett Sala

ho un po 'd'accordo con la sua dichiarazione "RDM e SRP andare mano nella mano, non sono in conflitto tra loro."Nella mia esperienza, quando la SRP è sottovalutata, porta a un modello di dominio anemico." No, non possiamo né aiutiamo a supportare alcuna persistenza, no, non possiamo fare 21-CFR11, no, non possiamo nemmeno che cosa una GUI è ..." e la classe finisce per fare nulla e solo un modello di dominio anemico.

e se RDM è sottovalutata (questa è la direzione/errore tendo a cadere in) allora SRP cade completamente nel dimenticatoio e alla fine noti che la tua classe ha centinaia di metodi e chiaramente sta facendo troppo.

Hai bisogno di trovare un equilibrio, il mezzo felice in cui stanno accadendo sia RDM che SRP. dura e spesso coinvolge più sentimenti e politica all'interno della tua squadra rispetto a quelli tecnici o regole.

"Conosci te stesso". Se sei come me e tendi a classi troppo complesse, sii consapevole. E quando vedi la classe di qualcun altro che sembra troppo complessa anche a te, quella grande bandiera rossa. Allo stesso modo, se sai che sei abbastanza duro con SRP e vedi una classe che sembra anemica anche per i tuoi standard, è un odore di codice importante.

Ora, rispondendo in qualche modo alla domanda dell'OP sull'archiviazione, penso che molto dipenda da quanto stabili, standard e astratti siano gli archivi. Se Storage fosse una qualche astrazione standard di XML, CSV o RDB, non ho assolutamente alcun problema con gli oggetti che sanno come memorizzarsi.

+0

SRP dice che una classe deve avere una ragione per cambiare, e significa una fonte di ragione per cambiare. Quindi, quando esistono comportamenti diversi per un oggetto, devono essere separati in classi diverse e quelle classi (che sono servizi in DDD) appartengono al modello di dominio. –