We are following Domain Driven Design for the implementation of a large website.
However by putting the behaviour on the domain objects we are ending up with some very large classes.
For example on our WebsiteUser object, we have many many methods - e.g. dealing with passwords, order history, refunds, customer segmentation. All of these methods are directly related to the user. Many of these methods delegate internally to other child object but
this still results in some very large classes.
I'm keen to avoid exposing lots of child objects e.g. user.getOrderHistory().getLatestOrder().
What other strategies can be used to avoid this problems?
The domain-driven approach is here to solve the complexity of software development. On the other hand, you can use emergent design when the challenge is simple. However, when your application is complex, the complexity will only grow, and so will your problems. Domain-driven design bases on the business domain.
Domain Driven Design (DDD) has recently gained additional popularity, as evidenced by new books, conference talks, and even complete conferences dedicated to it), and lots of trainings – including some by our very own colleagues here at INNOQ.
Domain-Driven Design(DDD) is a collection of principles and patterns that help developers craft elegant object systems. Properly applied it can lead to software abstractions called domain models. These models encapsulate complex business logic, closing the gap between business reality and code.
Thus, we have developed three strategies for extracting and formulating domain-specific design principles: (1) analyze the best hand-designed visualizations in the domain, (2) examine prior research on the perception and cognition of visualizations, and, when necessary, (3) conduct new user studies that investigate how ...
The issues you are seeing aren't caused by Domain Driven Design, but rather by a lack of separation of concerns. Domain Driven Design isn't just about placing data and behavior together.
The first thing I would recommend is taking a day or so and reading Domain Driven Design Quickly available as a free download from Info-Q. This will provide an overview of the different types of domain objects: entities, value objects, services, repositories, and factories.
The second thing I would recommend is to go read up on the Single Responsibility Principle.
The third thing I would recommend is that you begin to immerse yourself in Test Driven Development. While learning to design by writing tests first won't necessarily make you designs great, they tend to guide you toward loosely coupled designs and reveal design issues earlier.
In the example you provided, WebsiteUser definitely has way too many responsibilities. In fact, you may not have a need for WebsiteUser
at all as users are generally represented by an ISecurityPrincipal
.
It's a bit hard to suggest exactly how you should approach your design given the lack of business context, but I would first recommend doing some brain-storming by creating some index cards representing each of the major nouns you have in your system (e.g. Customer, Order, Receipt, Product, etc.). Write down candidate class names at the top, what responsibilities you feel are inherent to the class off to the left, and the classes it will collaborate with to the right. If some behavior doesn't feel like it belongs on any of the objects, it's probably a good service candidate (i.e. AuthenticationService). Spread the cards out on the table with your colleges and discuss. Don't make too much of this though, as this is really only intended as a brainstorming design exercise. It can be a little easier to do this at times than using a whiteboard because you can move things around.
Long term, you should really pick up the book Domain Driven Design by Eric Evans. It's a big read, but well worth your time. I'd also recommend you pick up either Agile Software Development, Principles, Patterns, and Practices or Agile Principles, Patterns, and Practices in C# depending on your language preference.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With