GUISA
Entra
|
Registrati
|
Aiuto
Home
Chi siamo
Blog
Forum
Media
Caffetteria
Architettura e design
Metodologia e processo
Forum
»
GUISA
»
Architettura e design
»
Domain Model: ok, fucilatemi...
Domain Model: ok, fucilatemi...
rated by 0 users
This post has 3 Replies | 2 Followers
Post
268
Punteggio 4.907
Rispondi
petrux
Posted: 06-07-2010 18.56
rated by 0 users
...ma io ancora non ho capito la differenza tra un DomainModel e un
banale modello delle entità con la business logic implementata dai vari
I*Service (anche se ho letto il libro di Andrea :-p). Qualche link?
Ciao e grazie,
Giulio
--
| Punteggio Post: 20
Post
67
Punteggio 1.440
Rispondi
Andrea Saltarello
In risposta a
06-10-2010 15.53
rated by 0 users
Semplificando, in DDD:
le entità non sono anemiche ma contengono anche tutta l'algebra che le riguarda direttamente
la logica che coinvolge più entità sta dentro servizi
I servizi sono:
"domain services" se la logica è usata "tale e quale" indipendentemente dal caso d'uso
"application services" (application layer) se servono a casi d'uso specifici
"infrastructure services" se sono ad uso e consumo di tutti (es: messaging, logging, ...)
ti "torna"?
.A
Inserito sotto:
services
,
domain model
,
DDD
| Punteggio Post: 35
Post
268
Punteggio 4.907
Rispondi
petrux
In risposta a
06-10-2010 17.13
rated by 0 users
Ciao andysal,
andysal wrote:
> ti "torna"?
A parole torna tutto magnificamente, non c'è che dire. Mi manca un
esempio concreto (magari comparativo).
> Semplificando, in DDD:
>
> * le entità non sono anemiche ma contengono anche tutta l'algebra
> che le riguarda direttamente
Esempio:
class Foo {
protected Foo(string l) { this.Label = l; }
string Label { get; private set; }
public static Foo CreateFoo(string label) { ... }
}
se ho il vincolo che la label sia unica, dove va "cablato"? Nella
factory di Foo?
> * la logica che coinvolge più entità sta dentro servizi
più entità della stessa classe o tipi diversi di entità?
(Ti sto prendendo sullo sfinimento, eh? )
> I servizi sono:
>
> * "domain services" se la logica è usata "tale e quale"
> indipendentemente dal caso d'uso
> * "application services" (application layer) se servono a casi d'uso
> specifici
> * "infrastructure services" se sono ad uso e consumo di tutti (es:
> messaging, logging, ...)
Qui siamo chiarissimi. :-)
Ciao e grazie,
petrux
--
| Punteggio Post: 5
Post
268
Punteggio 4.907
Rispondi
petrux
In risposta a
06-11-2010 10.58
rated by 0 users
Ciao andysal,
riguardo all'altra mia risposta, un esempio facile facile per iniziare
te lo propongo io.
andysal wrote:
> Semplificando, in DDD:
>
> * le entità non sono anemiche ma contengono anche tutta l'algebra
> che le riguarda direttamente
> * la logica che coinvolge più entità sta dentro servizi
Supponiamo di avere:
enum ActivityStatus
{
Unstarted,
InProgress,
Postponed,
Reassigned,
Complete,
Canceled,
}
class Activity
{
ActivityStatus Status { get; set; }
}
la logica intrinseca alla classe Activity prevede che:
a) quando una Activity viene creata il suo status è posto a Unstarted;
b) una volta cambiato lo stato da Unstarted -> * non è più possibile
ri-assegnare Unstarted;
c) una volta assegnato Complete/Canceled non è più possibile cambiare
status;
d) la transizione Unstarted --> Canceled è *PROIBITA* (questo mi serve
per incasinare un po' le cose ed arrivare al punto).
A occhio mi verrebbe da dire che in un ottica DDD la logica per la
verifica di questi vincoli vada cablata nel setter della property
Status; in questo modo avrei una cosa del tipo:
class Activity
{
private ActivityStatus status = ActivityStatus.Unstarted;
public virtual ActivityStatus Status
{
get { ... }
set { ...logica... }
}
}
Ragionando sui 4 vincoli sopra esposti:
a) la prima idea che mi viene in mente è di esporre un unico costruttore
(o factory che richiama un .ctor() protected) che abbia questa logica qui:
public/protected Activity()
{
status = ActivityStatus.Unstarted;
}
ovviamente nel repository/servizio docuto ci dovrà essere un controllo
sul metodo Add() per cui, se lo status è diverso da Unstarted viene
sollevata una ArgumentException.
b/c) non presentano particolari problemi: quando l'entità viene letta
dalla persistenza viene invocato il ctor() che setta lo status a
unstarted, poi viene assegnato un valore che sarà comunque possibile
tranne ne caso in cui...
d) ...tranne nel caso in cui il valore di destinazione sia Canceled.
I problemi sono questi:
1) Qualora esponessi un metodo SetStatus() e rendessi private il setter
della property, il mio DAL (ottenuto con NHibernate, EF) potrebbe
settare il valore di status 'as is' richiamando il setter privato della
peoperty via reflection?
2) oppure bisogna necessariamente esporre un altro costruttore/factory
method per la creazione di una entity con un dato status?
3) riguardo alla risoluzione del punto 'a' sopra proposta, il fatto di
avere un controllo sull'Add() del repo/service non causa uno
"sparpagliamento" della logica in più punti (un po' qui e il resto nel
setter della property o metodo SetStatus())?
Spero di essere stato chiaro.
Ciao e grazie,
petrux
--
| Punteggio Post: 5
Precedente
|
Successivo
Pagina 1 di 1 (4 elementi) |
RSS