2009-08-26 17 views
5

Due domande di partePrincipi di progettazione DDD e ASP.NET MVC

Ho un aggregato di prodotto che ha;

prezzi PackagingOptions ProductDescription immagini prodotto ecc

Ho modellato un repository del prodotto e non creare singoli repository per una qualsiasi delle classi figlie. Tutte le operazioni di DB sono gestite attraverso il repository del prodotto.

Sono in grado di comprendere correttamente il concetto DDD? A volte mi viene in mente che avere un repository consente di dire che le opzioni di packaging possono semplificarmi la vita recuperando direttamente un'opzione di packaging dal DB usando il suo ID invece di chiedere al repository del prodotto di trovarlo nella sua collezione di PackagingOptions e dare a me ..

seconda parte sta gestendo la modifica creare operazioni utilizzando ASP.MVC lavoro della struttura

attualmente sto cercando di gestire tutti aggiungere Modifica Rimuovi di queste collezioni bambino di prodotto attraverso il regolatore di prodotto (suona bene?).

Una sfida che sto affrontando è;

Se modifico un'opzione specifica confezionamento del prodotto attraverso

mydomain/prodotto/editpackagingoption/10

ho accesso alla id dell'opzione confezione

Ma io non ho il L'ID del prodotto è di per sé e questo mi obbliga a scrivere una query per trovare prima il prodotto che ha questa specifica opzione di imballaggio, quindi modificare quel prodotto e l'opzione di imballaggio revelant. Posso farlo perché tutte le opzioni di packaging hanno il loro ID univoco, ma questo fallirebbe se avessi collezioni che non hanno un ID univoco.

che si sente molto male ..

L'opzione successiva ho pensato sta inviando entrambi gli ID di opzioni di confezione del prodotto e sulla url del tipo;

mydomain/prodotto/editpackagingoption/3/10

Ma io non sono sicuro se questo è un buon design sia.

Quindi sono a un punto che sono un po 'confuso. potrebbe avere fraintendimenti fondamentali intorno a tutto questo ...

Apprezzerei se sopportassi la lunga domanda e aiutami a metterlo insieme. Grazie!

+0

Buona domanda. Non posso rispondere, ma sul fatto che non ho l'id prodotto, importa? Se è un one-to-one allora forse PackingOption dovrebbe avere il proprio ID prodotto? – jeef3

+0

Ha un productid, persistente nel database. la sfida è come ci arrivo senza avere un repository di packagingoption. – kaivalya

risposta

3

Nella mia mente, questa è una di quelle cose fangose ​​che si apre in DDD.

Nel codice, considero una radice aggregata come un contenitore per qualsiasi "relazione" che ha e qualsiasi oggetto entità che non può esistere senza la radice Aggregate.

Ad esempio, prendiamo l'esempio Cliente-> Ordine-> LineItem-> Esempio di prodotto che è stato ridotto a mano a randellate. La radice aggregata come l'ho visualizzata è cliente in questo scenario. Ciò detto, non si vuole sempre arrivare all'ordine tramite il cliente.Potresti voler trovare ordini in una data specifica.

Accendendo il suo lato, non avresti nemmeno un cliente che non ha un ordine. I due sono in una relazione alquanto simbiotica, quindi non si è la radice aggregata dell'altro.

Il punto è che non si desidera caricare un cliente tramite un ordine, ma non necessariamente si desidera caricare un ordine tramite il cliente.

A partire dall'ordine, tuttavia, è improbabile che desideri semplicemente recuperare un oggetto LineItem e sicuramente non lo creerai senza un ordine. A tal fine, l'Ordine funge da gateway per LineItems. LineItems non avrebbe bisogno del proprio controller o repository. Esiste solo all'interno dell'Ordine stesso e, come tale, fa parte dell'Ordine (in questo caso, l'Ordine diventa la radice aggregata) e viene gestito dall'Ordine Ordine.

Tuttavia, un LineItem probabilmente avrà una relazione con un Prodotto all'interno del sistema. I prodotti dovrebbero avere i propri controller, repository, ecc. Perché possono esistere al di fuori della radice Aggregate.

In sintesi al mio vagabondaggio, tendo a guardarlo in questo modo: se un'entità può esistere da sola, dovrebbe avere un controller. Le entità che non possono esistere da sole (LineItems in questo caso) devono essere gestite esclusivamente dal loro contenitore (radice aggregata).

Un po 'di purista DDD mi correggerà se/dove ho torto?

Per quanto riguarda la seconda parte della tua domanda, avrei bisogno di ulteriori dettagli su come immagini queste altre Entità. Con quello che hai messo qui, immagino che PackagingOptions sia legato a un prodotto e faccia parte di una radice aggregata del prodotto. Ora, implicando che si sta modificando, si chiede se questa sia una tabella di ricerca nel sistema o siano valori unici e, come tali, dovrebbero essere trattati come oggetti valore?

+0

Grazie per la risposta. Sembra che fossimo stati sulla stessa pagina finché non mi sono avvicinato ad un approccio più radicale per aggregare le radici che hanno sollevato tutte queste domande .. Per quanto riguarda la tua domanda; packagingoption Penso che dovrebbero essere oggetti di valore, lo esaminerò di nuovo. Ma la mia domanda rimane su come fare gli scenari di modifica per le entità di una radice aggregata dove passo il controllore l'id dell'entità figlio e spetta al controller aggregato per gestire tutto il resto - mi piace risuonare verso l'invio dell'ID aggregato e l'id del bambino per questi casi ma si sente ancora in disordine – kaivalya

+0

Direi che se un'entità figlio ha un ID e quell'entità deve essere modificata, garantisce il proprio controller. Per quanto riguarda la relazione genitore, se è 1: 1, quindi memorizzare l'id genitore con il bambino e solo afferrarlo, ma salvare il genitore per modificare un bambino che ha il suo id è un po 'maleodorante per me. Se stai modificando l'entità stessa, allora non stai modificando l'aggregato e hai qualcosa che dovrebbe essere in grado di stare da solo. Mi sembra che tu voglia modificare il Prodotto caricando un ordine e questo non funzionerà. Inoltre, gli oggetti valore non hanno identità - beh, di solito. – andymeadows

+0

Vedere http://devlicio.us/blogs/casey/archive/2009/02/13/ddd-entities-and-value-objects.aspx come punto di partenza per una discussione su entità e oggetti valore. – andymeadows

1

Kaivalya,

quanto riguarda il tuo ultimo commento (http stateless):

Dipende dal contesto. Prima di entrare nei dettagli, dovrei dirvi un principio di base sugli aggregati:

Gli aggregati definiscono un gruppo di oggetti correlati che devono essere trattati come una singola unità ai fini della modifica dei dati.

Questo è estremamente importante. Lo scopo di avere Aggregati è far rispettare gli invarianti. Ad esempio, potresti avere una politica del tipo "Un ordine non può superare i $ 500". Quindi, per applicare questa politica, inserisci Ordine e OrderItem insieme nell'ordine aggregato. In questo modo, ogni volta che aggiungi un nuovo OrderItem, dovrebbe essere aggiunto tramite l'oggetto Order. Lì, puoi controllare il prezzo totale e assicurarti che non superi i $ 500. Se non hai tali invarianti nel tuo dominio, allora non ha senso caricare tutti questi oggetti insieme.

Ora, tornando al tuo commento:

Se si dispone di invarianti che devono essere applicate, allora è bene per caricare l'intero aggregato anche se può avere un certo overhead. Sì, HTTP è senza stato e si carica l'intero aggregato solo per modificare uno dei suoi oggetti figlio e quindi buttarlo fuori. Va bene. La cosa più importante qui è che imponi le tue invarianti. Questo è ciò che DDD è per.

Lo scopo di DDD è quello di acquisire tutte le logiche di business nel proprio dominio.Potresti ottenere sicuramente prestazioni migliori se non dovessi caricare l'intero aggregato, ma come imporvi i tuoi invarianti? Molto probabilmente dovresti farlo nella procedura memorizzata. Sì, funziona, ed è veloce, ma affrontare le logiche di business nelle stored procedure durante la manutenzione è un incubo. Ecco perché il DDD si è evoluto. In questo modo è possibile modellare i requisiti aziendali utilizzando linguaggi/strumenti orientati agli oggetti, in modo che siano più facili da comprendere e modificare.

Basta ricordare, DDD è un ottimo approccio, ma non per tutti i tipi di progetti. Se hai a che fare con un progetto in cui ci sono molte logiche di business e le possibilità che cambino a causa della natura di un'azienda sono alte, allora dovresti usare DDD. Tuttavia, se il tuo progetto è più di "leggere qualcosa/scrivere qualcosa" senza molta logica aziendale, usare DDD è un mal di testa. Puoi semplicemente usare LINQ to SQL (o SqlDataAdapters) e inviare i tuoi oggetti alle tue Views. Non hanno nemmeno bisogno di preoccuparsi di trovare Enti, oggetti di valore, Aggregati, Repository, ecc

Spero che questo aiuti,

Mosh