views:

213

answers:

2

According to this definition, Fowler's concept of Anemic Domain Model is:

a software domain model where the business logic is implemented outside the domain objects

and

With this pattern, logic is typically implemented in separate classes which transform the state of the domain objects. Fowler calls such external classes transaction scripts.

If we take the example of a shopping cart, the Cart object would be the domain object. But to process the cart through to the final order and receipt involves checking the order inventory and processing the credit card payment. A lot of these things require utility classes since doing everything just inside the Cart object would mean that the Cart class would be huge and cumbersome. So, does that mean that the Cart in this example would be an Anemic Domain Model and these utility classes would be "transaction scripts" according to the definition above?

+2  A: 

A key concept of domain-driven design is to create a rich design that conveys and reflects the jargon of its domain experts (business users). Then, you want your code to become an expression of that domain model. (see "Ubiquitous Language" and "Model-Driven Design" in the DDD Patterns summaries).

When you do this, you will create names for your entities (classes) that reflect how a business user might describe them. Additionally, you will then create methods on those classes that also reflect the domain.

With this in mind, it may be helpful to consider how you think about your "helper" or "utility" classes. Using some of your descriptions, you might have classes and method such as:

product = GetProduct(data.productId);
shoppingCart.add(product);
receipt = customer.Purchase(shoppingCart);

Your Customer.Purchase method might do things like:

creditCard = this.getCreditCart(creditCardNumber);
purchaseNumber = creditCard.Charge(shoppingCart.Total);

I realize these examples are not complete or even fully accurate, but I hope the idea is helpful.

In response to your original question -- Yes, it is OK to have utility an support classes. However, you want to create those support classes and map them to real domain entities. After some work with your users, you will probably be able to create meaningful domain entites that are more than transaction script entities.

Hope this helps. Good luck!

Chris Melinn
Forgive my curiosity, but the question, as I understood it, was about the _anemic domain model_ which completely forbids methods like the above Purchase() in domain classes.With the anemic domain model the domain classes do have nothing more than getters/setters and you'd end up with all (!) behaviour implemented outside the domain classes.So, with the above assumptions, adopting the anemic domain model will force you to use helper/utility classes, since you have no other choice!Why not use the best of both worlds: Universal algorithms in the domain model and the rest outside!Stefan
struppi
@struppi - Why do you say methods like the above Purchase() would be forbidden? This method would likely be more than getting/setting, as it would contain business logic to perform the purchase.
Chris Melinn
+1  A: 

As Chris said it is OK to have utility an support classes if those support classes are mapped to real domain entities discovered from the user's language. Sometimes a lot of "helper classes" is a symptom of an anemic model if are related to classes that mainly have setters & getters (in those scenarios helpers grows up from behavior that isn't correctly assigned to domain objects).

JuanZe