0
votes

I was reading about anemic domain model is a antipattern and I had some questions about. I have a database where three clients uses and each one of them has diferrents business rules to insert a product into database. So, if I use a rich domain model, my code will be something like this:

public class Product: IValidatableObject
{
     public int Id;
     public Client Client;
     public int ClientId;

     public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
     {
          if (ClientId == 1)
               DoValidationForClientOne();
          else if (ClientId == 2)
               DoValidationForClientTwo();
          else if (ClientId == 3)
               DoValidationForClientThree();
     }
}

well, it's horrible, isn't? Now if I have an anemic domain model I could simple create three services layer classes where each one of them would contain a validation for one especific client. Isn't it good?

My second argument is: if I have a desktop and a web application using the same rich domain model, how can I know when to throw a HttpException and when to throw some desktop exception? Wouldn't it better to separate it? So, finally, why an anemic domain model is an anti pattern in a situation like this in my project?

3
That's not a domain model. That's a DTO with validation. blog.gauffin.org/2012/06/protect-your-datajgauffin

3 Answers

1
votes

An AnaemicDomainModel has its place: https://softwareengineering.stackexchange.com/questions/160782/are-factors-such-as-intellisense-support-and-strong-typing-enough-to-justify-the

Your domain model should not be throwing exceptions that are specific to a presentation platform. Let your presentation code sort that out. You should aim to make your domain model agnostic of its presentation.

1
votes
  1. As already stated - you showed just a DTO, not a domain entity.
  2. In DDD, you would have some constant rules directly in Product entity and some number of ProductPolicies to encapsulate what can differ in handling products in defferent contexts. Horrible? No. Beautiful and powerful. But only if your domain is complex enough. If it's not - use an anemic model.
  3. Your domain should not depend on anything. Should not know anything about web platform, desktop platform, ORM being used, DI container being used. So if you throw an exception, it should be a domain custom exception. Read about onion architecture or hexagonal architecure for more detailed explanation: http://jeffreypalermo.com/blog/the-onion-architecture-part-1/
0
votes

I will recommend following:

  • Define IProductValidator interface, and provide 3 implementations as:

    interface IProductValidator {
        void validateProduct(Product product);
    }
    
  • Change Client class, and add following methods to it

    class Client {
        void validateProduct(Product product) {
            getProductValidator().validate(product);
        }
    
        IProductValidator getProductValidator() {
           // this method returns validator, and it's better the method 
           // be abstract, and be implemented in sub-classes according 
           // to their type
        }
    
    }
    
  • And change the Product class to:

    public class Product: IValidatableObject {
        public int Id;
        public Client client;
    
        public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
            client.validate(this);
        }
    }
    

Now tou