如何用DDD为这种情况建模?

时间:2018-06-25 11:52:00

标签: domain-driven-design

使用DDD对这种情况进行建模时遇到一些问题。
我在同一BC中有两个实体:机器。有几种不同类型的油,其最终成本基于某些属性(密度,材料,购买价格等),并且会定期更新。因此,它们不在同一聚合中。由于它们是不同的实体,因此Machine仅包含其ID为油的参考

class Oil
  id
  purchase_price
  density
  material
  ...

class Machine
  id
  idOil
  cost
  addOil (Oil)
  ...

基于油的成本和其他一些机器属性,机器也有成本。 机油是可选的,因此在调用addOil方法时,机器会保存其id并使用机油成本来计算机器成本。
Machine中没有calculateCost方法。 机器有责任在其某些属性更改时更新其成本
问题是当我需要重新计算不带 Oil 油类的机器成本时(我只有ID)。哪种是最好的建模方法?我以为有一些,但没有一个能说服我:

1) Inject Oil class 。我认为这是不可能的,因为石油是一个实体,而DDD不允许这样做。
2)在机器构造器中注入油库。从1开始,DDD不允许。
3)在计算机构造函数中注入机油值对象。这意味着在调用addOil方法时,我必须使用Oil实体的副本而不是仅使用其id保存一个OilVO类。
4)构建汇总。我不喜欢,因为石油有自己的编号,并且还有其他一些类别(例如石油)参与了机器成本。机器会变得太大。
5)将石油成本计算器委托给域服务。这意味着每次创建Machine对象时,都必须在Machine构造函数中注入此服务接口:

interface OilCostCalculatorService (OilRepository repo) {
  ...
  public double calculateCost (IdOil id) { 
     Oil oil = repo.getOil(id);
     double cost = .... // calculate cost from oil properties
     return cost;
  }
}

class Machine {
  public Machine (OilCostCalculatorService service, ...) { ... }
}

6)也许我的班级建模不正确,但经过很多考虑,这并不是我最好的方法。

1 个答案:

答案 0 :(得分:2)

  

问题是当我需要重新计算不带机油等级的机器成本时(只有ID)。哪种是最好的建模方法?

由于机器和机油彼此隔离(单独的集合),因此机器计算无法使用“当前”机油价格-如果没有互锁,则当前的机油价格可能会同时变化对机器的更改。

因此,机器正在使用油价的缓存副本。

因此,答案之一是在机器中汇总最近一次已知油价的缓存副本,并将其用于估算成本。

另一种可能性是将域服务传递给计算机,该域服务是一个接受计算机ID并返回成本的缓存副本的函数。这看起来有点像您的选项5,除了将服务作为参数传递给,而不是将服务注入到构造函数中。

在任何一种情况下,您都可能希望调查您的域是否需要明确的时间模型(周一至周一的油价)。在许多领域中,都有报价的概念,该概念有时会制定,有时可能会持续很短一段时间,在此期间价格将是固定的(报价的提供者基本上会承担任何真实价格可能会发生变动的风险无法获利)。