Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

Domain Driven Design: Business logica in aggregates

Pagina: 1
Acties:

  • mithras
  • Registratie: Maart 2003
  • Niet online
De laatste tijd ben ik mezelf een beetje in domain driven design aan het inlezen. Ik merk dat ik al een tijdje een soort-van het gedachtegoed gebruik en dat het lezen over DDD mijn eigen "uitvindingen" bevestigt.

Echter zit ik nog wat met aggregates in mijn maag. Waarvoor gebruik je het precies voor? Is het puur een leeg omhulsel? Als ik lees over aggregates link ik dit direct (ik schrijf nu eenmaal veel php) aan een Doctrine\Common\Collections\Collection: een simpele interface die een soort object-georienteerde array is.

Een onderdeel van de collection:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
interface Collection
{
    // meer hier

    /**
     * Returns all the elements of this collection that satisfy the predicate p.
     * The order of the elements is preserved.
     *
     * @param Closure $p The predicate used for filtering.
     * @return Collection A collection with the results of the filter operation.
     */
    function filter(Closure $p);

    /**
     * Applies the given function to each element in the collection and returns
     * a new collection with the elements returned by the function.
     *
     * @param Closure $func
     * @return Collection
     */
    function map(Closure $func);
}


Je kan zo best veel business logic kwijt in een collection. Naast dit soort zaken (filtering) kan ik ook bijvoorbeeld sorteren in een collectie. Echter, is dat een functie van een aggregate?

Ik zou niet zo snel een ander goede plek weten binnen DDD waar je filtering en sortering kan toepassen. Business logic van dit soort dingen zou ik liefst niet in entiteiten kwijt zijn. Value objects zijn niet echt toepasbaar lijkt me. Is dit een service taak? Dat is meer "alles wat je niet elders kwijt kan", maar juist een aggregate kan wel filtering/sortering bevatten, lijkt me.

Iemand enige ervaring hiermee?

  • Hydra
  • Registratie: September 2000
  • Laatst online: 06-10 13:59
M.i. is DDD een design methodology en heb je het nu over de technische implementatie. Wat betreft aggregates stellen ze dat een aggregate de onderliggende objecten beheert en de rest van het systeem uberhaupt geen referenties kan krijgen naar die objecten. Hoe en waarop je filtert/sorteert is eerder een technische implementatie die volgt uit je design.

Ik ben allesbehalve een expert op het gebied van DDD en ik moet zeggen dat ik niet helemaal zie hoe een aggregate kan voorkomen dat je referenties naar onderliggende objecten onbenaderbaar maakt en ondertussen toch bruikbaar blijft. Dus ik vermoed dat je in de implementatie erop uitkomt dat een aggregate een collection met ingebouwde business logic is.

https://niels.nu


Verwijderd

Deze pagina beschrijft het redelijk goed: Wikipedia: Domain-driven design

Maar ik denk dat je liever een praktisch voorbeeld wilt :)

Context: online webshop - order proces

Fout: vanuit een OrderController->Checkout Action

var customer = GetCustomer();
var order = new Order()
foreach(cartitem in Cart){
line = order.AddOrderLine( ... )
if (sale)
{
ApplySale(line)
}
}
order.Customer = customer.
etc.

Als jouw controllers er ZO uitzien, dan mis je dus een aggregate root.

Kort door de bocht is de Aggregate root het 'hoofd' object die alle processen en data binnen een 'bounded context' afhandeld. Het zorgt ervoor dat er geen foute processen uitgevoerd kunnen worden en geen foute data je domein in kan komen. Bv: vergeten de AddSales functie aan te roepen vanuit de webcontroller.

bovenstaand voorbeeld zou dus ongeveer moeten gaan als:

OrderController->Checkout

cart = CurrentCart();
order = cart.CreateOrder();

(punt)

De bounded context hier is 'maak op basis van mijn cart een order'. De beheerder van dit proces? Jep: de Cart.
Want de Cart heeft hier alle info om een nieuwe order aan te maken.

Vanuit jouw 'client' code, kan je nooit fouten maken of vergeten een bepaalde functie aan te roepen. Dat is immers jouw taak niet. dat is de taak van het domein model.

Complexere processen die over meerdere 'bounded contexts' gaan, worden beheerd door een service.

Je client-code voert dan de service uit. Bv:

package = GetPackage()
customer = GetCustomer()

shipmentService.ShipPackageToCustomer(package, customer);


Overigens is puur DDD ontwikkelen niet bedoeld voor simepele CRUD apps (create/read/update/del.).
DDD (Domain Driven!) is echt bedoeld om een maatwerk software model precies aan te sluiten bij de processen en data waar de software voor dient.
Voor simpele in/uitvoer applicaties is het niet eens alleen overkill, je hebt daar gewoon geen 'domein'.

Simpel voorbeeld:
Facebook: veel data, weinig complexe processen. Die gebruiken voor facebook.com front-end zeker geen DDD.
Belastingdienst: complexe domein materie, veel regels en uitzonderingen, veel diverse data, Ideaale candidaat voor DDD.

Koop overigens ook dit boek: http://books.google.nl/bo...driven+design&redir_esc=y
Zowat de heilige graal onder de DDD architectuur boeken.

Success verder, ik hoop dat je hier wat aan hebt.