2009-08-26 16 views
9

Diciamo che ho l'entità tipica autoDDD: sottoclassi e le entità di radice

class Car : Entity 
{ 
    public double MaxSpeed { get; set; } 
    public Color Color { get; set; } 
    /* ... */ 
} 

Questa entità, nel mio modello di dominio, sarebbe l'entità radice di un Aggregate.

Ora diciamo che io specializzo le macchine. Creo un Ferrari, ed i felici possessori di Ferrari piace chiamarli con un soprannome:

class Ferrari : Car 
{ 
    public string Nickname { get; set; } 
} 

Diciamo che ho un altro soggetto, il società entità. Sarebbe l'entità root di un altro Aggregate. Ci sono molte persone che lavorano in un'azienda, rappresentata dall'entità Persona. Le persone possono avere macchine. Ma la Presidente di una società di solito è molto ricca e questo tipo di persone, hanno Ferraris:

class President : Person 
{ 
    public Ferrari Ferrari { get; set; } 
} 

In questa situazione, ho l'entità presidente, che è all'interno il società Aggregate, che contiene un riferimento a una Ferrari, una specializzazione dell'entità radice di un altro aggregato.

È corretto in vista della DDD? Posso/dovrei considerare la specializzazione delle entità root stesse come entità root dello stesso aggregato? Voglio dire, nel dominio che ho descritto, è l'entità Ferrari anche l'entità radice del Car Aggregate (dal momento che Ferrari è anche un'auto)?


Ora diciamo che devo persistono questo modello a un database. Penso che la mia domanda non dipenda dal framework OR/M che userò.

Come si crea la tabella con Automobili? Devo costruire un singolo tavolo Cars, con una colonna "CarType" (valori possibili: "Car", "Ferrari") e una colonna Nickname nullable?

Oppure dovrei costruire un tavolo per Auto e un tavolo per Ferrari, quest'ultimo con il suo PK e FK di automobili?

Grazie!

risposta

2

Penso che inizi a perdere molta della flessibilità del sistema creando tipi concreti di queste entità. Il tipo di relazione che stai insinuando è qualcosa che generalmente faccio con un'entità di "Tipo". Ad esempio, hai una macchina. Una Ferrari è un tipo di macchina. Le due entità che ne derivano sono un'auto e un CarType.

Nel modo in cui si sta parlando, è necessario aggiungere nuove entità ogni volta che viene introdotto un nuovo tipo. Se tutto ciò che stai cercando di catturare è il "soprannome" dell'auto, penserei che sia solo un altro pezzo di dati, e non un'altra entità. A meno che tu non abbia dati diversi (ad es.diversi nomi di proprietà) e/o differenze di comportamento nelle entità Car per diversi tipi, non si guadagna molto con questo approccio. Preferirei avere metodi di deposito come FindCarByType() e trattare con un tipo di entità, per ridurre il rischio.

Non sono affatto un esperto di DDD e sto lottando con alcuni concetti (o più come lottare con le molteplici interpretazioni di alcuni concetti). Sto scoprendo che non esiste un'implementazione pura al 100% e che ci sono delle sfumature per ogni implementazione che ho visto.

Modifica Segue

vedo che ho letto male parte di quello che aveva scritto. Vedo che il soprannome non è per tutti i veicoli, ma solo per la Ferrari: Car. Penso che la risposta sia davvero "dipende". Quanta specializzazione di dominio hai nel resto del tuo modello? Avere un soprannome potrebbe essere prevalente tra le entità Ferrari, ma è esclusivo? Non si tratta solo dei dati effettivi, ma dei requisiti. Fondamentalmente si tratta di quanta specializzazione ti aspetti in queste entità.

+0

Fantastico! Grazie! In realtà, nel mio sistema "reale", "Automobili" sono molto importanti, ma la "Ferrari" è la cosa più importante nel mio dominio, di cui non posso perdere traccia, devo fare statistiche su di esso. –

4

Non si dovrebbe utilizzare l'ereditarietà per modellare il dominio perché presto si presenteranno dei problemi una volta che il modello inizia a diventare complesso.

Il presidente è semplicemente un ruolo della persona e della persona può avere più ruoli. Forse il presidente ha solo un ruolo, ma è semplicemente casuale scegliendo un esempio sbagliato.

Ferrari non deve essere ereditato dalla macchina. Non è scontato sull'esempio della Ferrari, perché fanno solo un tipo di auto, ma considerano la compagnia che produce molti tipi come furgoni, berline, berline, camion e così via. Probabilmente vorrai creare classi per ogni tipo che erediterà dalla classe dell'auto. E poi cosa ... farai cinque classi Toyota che erediteranno da ogni tipo? Come ...

Car -> Sedan -> ToyotaSedan 
Car -> Truck -> ToyotaTruck 
Car -> Hatchback -> ToyotaHatchback 

Sarebbe ridicolo.

Disclaimer: Non so nulla di automobili. Tuttavia ...

Non utilizzare l'ereditarietà per modellare il dominio. Mai.

Provalo senza ereditarietà e sarà anche evidente come mantenere il tuo dominio.

+0

Grazie, lubrificanti.Ma in questo caso, nel mio dominio "reale", ho * "auto", e ci sono auto "generiche" e 2 tipi speciali di auto, "Ferrari" e "Porsche" che devono essere rintracciate, sebbene siano essenzialmente "Cars". –

+3

ancora, evitare l'ereditarietà. anche se non lo farai, dovrai farlo tra uno o due anni perché il tuo modello diventerà probabilmente più complicato in futuro per catturare nuovi requisiti e l'eredità causerà un sacco di sofferenza nel tuo progetto. esempi di libri di testo per spiegare l'ereditarietà come Gatto e Cane sono entrambi Animali e Cerchio e Quadrato sono entrambi forme che danno un'impressione sbagliata di ciò che è veramente un'eredità e i programmatori spesso abusano di questo potente concetto per la modellazione di domini. leggi qui: http://www.geocities.com/tablizer/oopbad.htm#overeng (io non sono l'autore) –

+0

Ottimo articolo! Grazie! –

3

Generalmente quando si attraversano i confini di aggregazione radice si consente solo al riferimento di essere dell'ID dell'altra aggregazione radice. Quindi si utilizza quell'ID per cercare l'altro aggregato nel proprio repository.

Quindi nel tuo caso vorrai che il Presidente abbia un ID auto e se hai mai avuto bisogno di fare qualcosa per l'auto del Presidente, dovresti usare l'ID auto per andare al deposito per prendere la macchina. Il presidente non avrebbe un riferimento alla stessa auto.

Ora su quella Ferrari. È un po 'difficile da applicare nella terminologia DDD standard. Normalmente si mettono delle convalide sull'assegnazione di una macchina a un presidente. O forse c'è un CarBuyingService solo per i presidenti che si assicura di farlo bene. Normalmente le specializzazioni DDD non sono esse stesse aggregati di root.

+0

Sei l'unico che ha effettivamente risposto alla domanda –