富域模型的坏处

时间:2012-11-29 16:05:10

标签: domain-driven-design design-patterns

我正在阅读关于贫血领域模型的反模式,我有一些问题。 我有一个数据库,其中三个客户端使用,并且每个客户端都有不同的业务规则来将产品插入数据库。 因此,如果我使用丰富的域模型,我的代码将是这样的:

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();
     }
}
好吧,这太可怕了,不是吗? 现在,如果我有一个贫血的域模型,我可以简单地创建三个服务层类,其中每个类都包含一个特定客户端的验证。不是很好吗?

我的第二个论点是:如果我有一个桌面和一个使用相同的富域模型的Web应用程序,我怎么知道何时抛出HttpException以及何时抛出一些桌面异常?将它分开不是更好吗? 那么,最后,为什么在我的项目中,贫困领域模型是一种反模式?

3 个答案:

答案 0 :(得分:1)

AnaemicDomainModel有它的位置:https://softwareengineering.stackexchange.com/questions/160782/are-factors-such-as-intellisense-support-and-strong-typing-enough-to-justify-the

您的域模型不应该抛出特定于演示平台的异常。让您的演示文稿代码排除。您的目标应该是使您的域模型与其表示无关。

答案 1 :(得分:1)

  1. 如前所述 - 您只展示了DTO,而不是域实体。
  2. 在DDD中,您可以直接在Product实体中使用一些常量规则,并使用一些ProductPolicies来封装在不同上下文中处理产品时可能存在的差异。可怕?没有。美丽而有力。但前提是您的域名足够复杂。如果不是 - 使用贫血模型。
  3. 您的域名不应该依赖任何内容。关于Web平台,桌面平台,正在使用的ORM,正在使用的DI容器应该不知道。因此,如果您抛出异常,它应该是域自定义异常。有关洋葱建筑或六边形建筑的更多详细解释,请参阅:http://jeffreypalermo.com/blog/the-onion-architecture-part-1/

答案 2 :(得分:0)

我会建议以下:

  • 定义IProductValidator接口,并提供3个实现:

    interface IProductValidator {
        void validateProduct(Product product);
    }
    
  • 更改Client课程,并向其添加以下方法

    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
        }
    
    }
    
  • 并将Product类更改为:

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

现在开始