domain driven development

Posts   
 
    
bunzee
User
Posts: 84
Joined: 20-Mar-2007
# Posted on: 29-Oct-2012 16:08:51   

Hi

I am a newbie at DDD. I have read in one of the post someone mentioned about domain driven development in llblgen V3. I wonder how llblgen generated ORM fits into DDD. From what I have read, DDD is big on putting the logic of managing an entity within that entity. I am more of an adpater fan. Does this mean using adapter I am out of luck as far as DDD is concern?

Thank you.

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 30-Oct-2012 06:10:37   

bunzee wrote:

I am a newbie at DDD. I have read in one of the post someone mentioned about domain driven development in llblgen V3.

I've read DDD before, but for me it's very subjective. IMHO if you follow OOP principles and divide your business logic in coherent/common-sense way, you will end up in what DDD is supposed to be (http://programmers.stackexchange.com/questions/123023/what-is-domain-driven-development-in-practical-terms)

You can see Adapter/SelfServicing as two opposite ways of doing things (where you put business logic), but at large applications you usually have the business logic somewhere else aside, and use the entities as a business facade set of objects. It's more like 'where is the persistence logic'.

Where does DDD says that the entities must contain logic to manage themselves? That's also merely subjective IMHO, but I'm not a pattern expert. What you should solve first is What is DDD? Why do you need it? and from there I'm sure you will find a fit with LLBLGen generated code simple_smile

David Elizondo | LLBLGen Support Team
bunzee
User
Posts: 84
Joined: 20-Mar-2007
# Posted on: 30-Oct-2012 17:51:43   

Hi Daelmo Here's the quote that from "http://msdn.microsoft.com/en-us/magazine/dd419654.aspx". Thanks.

Think of entities as units of behavior rather than as units of data. Try to put your logic in the entities that own them. Most times there's an entity that should receive some operation you're trying to add to your model, or a new entity is begging to be created or extracted. In more anemic code, you find a lot of service or manager classes that validate entities from the outside. In general,** I much prefer to do that from within the entity**—you get all the benefits associated with the fundamental principle of encapsulation, and you're making your entities behavioral.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39590
Joined: 17-Aug-2003
# Posted on: 31-Oct-2012 16:17:38   
Frans Bouma | Lead developer LLBLGen Pro
bunzee
User
Posts: 84
Joined: 20-Mar-2007
# Posted on: 11-Jun-2013 23:02:30   

Otis, I read your comment in the stackoverflow and I understand what you are saying. However, DDD does talk a lot about repository, service, entity, value, aggregate root. And the principle of SOLID. All of these equates back to codes, creating classes, where to put properties and where to put functions. For instance, in our current system we make our order and orderdetail classes straight from the DAL. We created OrderManager and OrderDetailManager classes that manage order and order detail. Not so good. We ran into cases where the orderdetail are updated (such as charges) and the order.TotalCharge is conflicted with OrderDetail. We have a large OrderManager where anything that has to do with Order is offered via API in OrderManager. Another bad idea. The OrderManager got so large and so out of hand.

If we are to follow DDD, we would have Order as aggregated root. Order offers CRUD that has to do with Order. Then we may have some service classes that deal with Order as well as Customer.

The examples above show how DDD affect the objects design. So DDD is not "It's a way of THINKING, not a way of writing code", don't you think?

Thanks

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39590
Joined: 17-Aug-2003
# Posted on: 12-Jun-2013 14:22:21   

bunzee wrote:

Otis, I read your comment in the stackoverflow and I understand what you are saying. However, DDD does talk a lot about repository, service, entity, value, aggregate root. And the principle of SOLID. All of these equates back to codes, creating classes, where to put properties and where to put functions.

But no-one has come up with a blue-print to do that properly. There's always vagueness and 'how to do this then?' questions, simply because there's no such thing as 'do this and it works'. That's also why the whole 'repository, service etc.' DDD blabla is putting people into a specific corner but without them knowing why.

The only reason I came up with why this is is because IMHO in general the people who look at the code side of DDD and not the aspects I talked about are people who think in code, not in concepts. Everything starts with code for them, insteads of that it ends with code as it should be. Again, IMHO.

For instance, in our current system we make our order and orderdetail classes straight from the DAL. We created OrderManager and OrderDetailManager classes that manage order and order detail. Not so good. We ran into cases where the orderdetail are updated (such as charges) and the order.TotalCharge is conflicted with OrderDetail. We have a large OrderManager where anything that has to do with Order is offered via API in OrderManager. Another bad idea. The OrderManager got so large and so out of hand.

If you'd called them OrderService and OrderDetailService, would it then make DDD look bad? Isn't this simply a problem with 'what goes where' as it has always been with OO? You have business logic which affects 1) fields, 2) entities and 3) (sub) models. 1) and 2) can be done inside the entity, or inside a class which focuses solely on a single entity (repository? Aggregate root class?, don't jump to conclusions quickly here, as things get very hairy with those too). E.g. with validator classes injected into the entities. 3) is cross-entity, so clearly outside the entity.

The problem you describe is that a value in entity A affects entity B. This is cross-entity and should be handled by something controlling these two, however you want to call these. Service? Repository? Manager?

If you look at this forum's code, we use 'manager's and gui helpers (which in modern speak would be called 'controllers'). They're here: https://github.com/SolutionsDesign/HnD/tree/master/BL

They're not focused on a single entity, they're focused on functionality, and consume entities. They all do, none are tied to a single entity. You see ThreadManager and ForumManager but these will consume other entities, however their role is solely to manage the functionality of a thread and a forum. One might have called these 'Services' instead, but frankly, who gives a hoot.

Your TotalCharge value is a nice example, as it will also wreck DDD principles, let's see how -> simple_smile

If we are to follow DDD, we would have Order as aggregated root. Order offers CRUD that has to do with Order. Then we may have some service classes that deal with Order as well as Customer.

That might be, but for TotalCharge, a service wouldn't help, would it? simple_smile Because here's the problem: you change values in a couple of OrderDetail rows. Are these an aggregate root? Or are these value types in the Order aggregate root and thus handled by the Order repository? If the former, so a real entity (and why wouldn't they, if you opt for 'value type', I'll give you the Customer.IsGoldCustomer example, which is a flag which is true if a customer has more than 10 orders of a total value of $100 or more wink ), you change the values of fields in orderdetail rows which affect a value in Order. But by what is that value in Order changed, or better: by what code and where is that located? It can only be located in the OrderDetail entity, as that one knows when a charge value is changed, but that creates a web of dependencies because now OrderDetail has to know about how to change a value in Order...

And that is the problem: you inevitably run into a situation where you have to change something from within a class but that requires a dependency on another class which wasn't there earlier. In the example above, one could say 'but orderdetails has a reference to its Order', but that's the thing: in DDD code, one goes through the repository to obtain the reference of an entity, not through a property!

In Order-OrderDetails this is less clear, as one will argue that OrderDetails isn't an aggregate root. However in the case of Customer.IsGoldCustomer it is clear that this is a problem, as that value is set based on changes / additions in order and order details which will always be outside the Customer aggregate root. This is the core of all the debates on DDD mailinglists: to avoid the web of dependencies, one has to move outside the entity classes, to services and use a rather empty domain model (except the BL which focuses only on 1 entity), but that is precisely what's said to be <deepvoice>'wrroooonngggg'</deepvoice>... (sorry about that, it's just that I've always found the string 'this is wrong' 'this is right' BS from DDD evangelists a bit funny, no offense to you btw)

The examples above show how DDD affect the objects design. So DDD is not "It's a way of THINKING, not a way of writing code", don't you think? Thanks

No, it's exactly about thinking and communication, and not about code. Forget code, use DDD for conversations with domain experts and the people who have to write the code, the Ubiquitous Language, as the domain is important, it's called domain driven, but domain doesn't mean 'code', it's about the world the problem(s) the application will solve appear and are located.

How you'll do that is up to you. If you want to use repositories and what not, go ahead. But if you want to do something completely different, you can do that too. It's so sad that the code always takes precedence over what's actually far more important, namely what problems you have to solve (domain problems, not code problems) and why.

Frans Bouma | Lead developer LLBLGen Pro