Domain Driven Development

87 views
Skip to first unread message

Alex Newman

unread,
Nov 11, 2015, 5:46:15 PM11/11/15
to Django users
I almost hate to bring this up, but we are reading Eric Evan's book "Domain Driven Development" at my company in our technical bookclub and some techniques in the book seem to be hard to apply in DJango. The main one being the notion of aggregations:

From  
http://martinfowler.com/bliki/DDD_Aggregate.html
"Aggregate is a pattern in Domain-Driven Design. A DDD aggregate is a cluster of domain objects that can be treated as a single unit. An example may be an order and its line-items, these will be separate objects, but it's useful to treat the order (together with its line items) as a single aggregate.

An aggregate will have one of its component objects be the aggregate root. Any references from outside the aggregate should only go to the aggregate root. The root can thus ensure the integrity of the aggregate as a whole."

Can we actually enforce this in django?

Avraham Serour

unread,
Nov 11, 2015, 6:38:38 PM11/11/15
to django-users
I believe you could call a queryset this thing, or this thing a queryset

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/aa759e76-0192-4103-89c7-0001ed666f26%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Mike Dewhirst

unread,
Nov 11, 2015, 8:15:01 PM11/11/15
to django...@googlegroups.com
On 12/11/2015 9:43 AM, Alex Newman wrote:
> I almost hate to bring this up, but we are reading Eric Evan's book
> "Domain Driven Development" at my company in our technical bookclub
> and some techniques in the book seem to be hard to apply in DJango.
> The main one being the notion of aggregations:
>
> From  http://martinfowler.com/bliki/DDD_Aggregate.html
> "Aggregate is a pattern in Domain-Driven Design. A DDD aggregate is a
> cluster of domain objects that can be treated as a single unit. An
> example may be an order and its line-items, these will be separate
> objects, but it's useful to treat the order (together with its line
> items) as a single aggregate.
>
> An aggregate will have one of its component objects be the aggregate
> root. Any references from outside the aggregate should only go to the
> aggregate root. The root can thus ensure the integrity of the
> aggregate as a whole."
>
> Can we actually enforce this in django?
>

No. But you can write methods in the aggregate root model as an API to
manage the child models. If you are disciplined it should work.

The main problem (I think) implementing Eric Evans aggregate is deleting
items within the boundary.

See
https://docs.djangoproject.com/en/1.8/ref/models/fields/#django.db.models.ForeignKey.on_delete

Maybe it would be possible to use a callable for the root model's
on_delete such that the constant returned is appropriate for the
circumstances.

It is interesting and would be very useful if you worked out how to do
it in a way we could all benefit.

Good luck.

Mike

> --
> You received this message because you are subscribed to the Google
> Groups "Django users" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to django-users...@googlegroups.com
> <mailto:django-users...@googlegroups.com>.
> To post to this group, send email to django...@googlegroups.com
> <mailto:django...@googlegroups.com>.
> <https://groups.google.com/d/msgid/django-users/aa759e76-0192-4103-89c7-0001ed666f26%40googlegroups.com?utm_medium=email&utm_source=footer>.

Vinicius Assef

unread,
Nov 12, 2015, 9:09:32 AM11/12/15
to Django users
Yes, and you should.

Note the "domain objects" cited from the book doesn't mean "model objects". In an active record model (as in Django) it can be a bit confusing, but you should have the so called Business Objects. It is what the book calls "domain objects". They are objects that map the "problem domain".

They are not models, as the Active Record lead us to think of. They are classes that "see the big picture". They use model classes and eventually other Business Objects classes, too.

So, this arrangement to guarantee integrity should lay not in model classes. Basically, the Active Record pattern maps one instance of the object to a table row and it has some drawbacks. For instance, an order without items is not an order at all. So, how to solve it using Active Record?

You don't. The pattern is not well suited for this case.

To make this in a proper way, you should create an object Order (not a model instance!), other object OrderItem and assure your rules go through Order. It's a basic entity relationship, with a strong and a weak entity. An OrderItem doesn't exist without an Order. So, you need an structure to represent a "full order" that don't map directly to a table row.

You should separate this in domain model objects. Yes, it looks like Java. But actually, it's design pattern.

I recommend you the talk "Architecture: The Lost Years", from Uncle Bob: https://www.youtube.com/watch?v=HhNIttd87xs

This article (http://blog.codefx.org/design/architecture/architecture-lost-years/) makes some analysis on the talk.

--
Vinicius Assef.

Tom Christie

unread,
Nov 17, 2015, 12:21:24 PM11/17/15
to Django users
Hi Alex,

I've written previously about encapsulation and Django models, and I think that's kinda relevant here.
If you apply the policy "never write to a model or call .save() directly" then yes, you can ensure that the only access points
for modifying the state of eg 'line items', is eg the owning 'order' instance.

In some cases there may not be an order instance as such (eg if you simply have an order id against the line items, but no fully fledged 'order' table in your database) in which case you'd apply the encapsulation either in the LineItem manager class, or in a helper class that represents and interacts with orders, but does not map directly to a database table itself.

A final consideration here is that these sorts of case *might* map well to cases where you want an element of document-structure in your data models, rather than relational  structure. (eg. a JSON field against the order that stores line item data) that call depends on what information you're going to need to index aggregate etc. Probably not what you need, but worth mentioning as an option.

Hope that helps give some food for thought.


  T.
Reply all
Reply to author
Forward
0 new messages