代码之家  ›  专栏  ›  技术社区  ›  Eli Bendersky

DDD,处理依赖项

  •  7
  • Eli Bendersky  · 技术社区  · 6 年前

    无聊介绍:

    我知道-DDD与技术无关。正如我所看到的,DDD就是要和产品所有者一起创建无处不在的语言,并以一种简单而结构化的方式将其反映到代码中,这样它就不会被误解或丢失。

    但这里出现了一个悖论——为了摆脱领域模型中应用程序的技术方面,至少从设计的角度来看,它是一种技术。

    上一次我试图跟踪DDD——它最终把域对象之外的整个逻辑变成了“魔力”服务和贫血的域模型。

    我学会了一些新的忍者把戏,想知道这次我能不能对付歌利亚。


    问题:

    class store : aggregateRoot { 
      products;
      addProduct(product){
        if (new FreshSpecification.IsSatisfiedBy(product))
          products.add(product);
      }
    }
    
    class product : entity {
      productType;
      date producedOn;
    }
    
    class productTypeValidityTerm : aggregateRoot {
      productType;
      days;
    }
    

    FreshSpecification 应该指定产品是否没有气味。为了做到这一点,它应该检查产品的类型,按天计算产品的新鲜时间,并与之进行比较。 producedOn . 种类简单。

    但问题来了- productTypeValidityTerm productType 应该由客户管理。他应该能够自由地添加/修改这些内容。因为我不能从产品到 产品类型有效期限 直接地,我需要以某种方式询问他们 产品类型 .

    以前-我会创造一些 ProductService 它通过构造器接收必要的存储库,查询术语,执行一些额外的voodoo并返回布尔值(将相关的逻辑进一步远离对象本身,并将其分散在谁知道的地方)。

    我认为这样做是可以接受的:

    addProduct(product, productTypeValidityTermRepository){...}
    

    但我又不能自由地从多个规范中组合规范,这是它们的主要优势之一。

    所以-问题是,在哪里做?商店如何知道条款?

    1 回复  |  直到 15 年前
        1
  •  2
  •   tijmenvdk    15 年前

    带着过于简单化的风险:为什么不让事实 Product 新鲜的东西是产品“知道”的吗?一 Store (或任何其他相关对象)不必知道如何确定产品是否仍然新鲜;换句话说,事实上 freshSpecification productTypeValidityTerm 即使存在也不应该为人所知 商场 ,只需检查 Product.IsFresh (或者可能是其他与现实世界更为一致的名字,比如 ShouldbeSoldBy , ExpiresAfter 等)。然后,产品可以知道如何实际检索 protductTypeValidityTerm 通过插入存储库依赖项。

    在我看来,你是在外部化行为,这应该是你的领域聚合/实体固有的,最终导致(再次)贫血的领域模型。

    当然,在一个更复杂的场景中,新鲜度取决于上下文(例如,预算商店中可接受的内容不被认为值得在高级商店中销售),您需要将整个行为从产品和商店中具体化,并创建一个完全不同的类型来模拟这种特定行为。

    在注释后添加

    对于我提到的简单场景,沿着这些线做一些事情:使 FreshSpec 产品集合的一部分,它允许 ProductRepository (这里注入了构造函数)在需要时加载它。

    public class Product {
      public ProductType ProductType { get; set; }
      public DateTime ProducedOn { get; set; }
      private FreshSpecification FreshSpecification { get; set; }
      public Product(IProductRepository productRepository) { }
    
      public bool IsFresh() {
        return FreshSpecification
          .IsSatisfiedBy(ProductType, ProducedOn);
      }
    }
    

    商店不知道这些内部结构:它只关心产品是否新鲜:

    public class Store {
      private List<Product> Products = new List<Product>();
      public void AddProduct(Product product) {
        if (product.IsFresh()) {
          Products.Add(product);
        }
      }
    }