解决贫血领域模型的例子

时间:2012-09-17 01:17:18

标签: domain-driven-design anemic-domain-model

我正在审查可以优化抵押贷款计算工具设计的区域,主要用于学习目的。在阅读了贫血领域模型后,我开始对创建富模型感兴趣,并注意到我目前的实施可能有贫血!以下是伪代码中的当前实现:

class MortgageCalculator {
  Mortgage mortgage; // mortgage object containing loanAmount, interest rate, etc.;
  calculateMonthlyPayment(); // calculates monthly payments using mortgage object's properties
}

class Mortgage { // Anemic?
  loanAmount;
  interestRate;
}

目前,Mortgage对象主要用于对象之间的数据传输等。

以下是我正在考虑的一些修订选项:

  1. 从MortgageCalculator中移除抵押贷款对象并使用抵押贷款 纯粹作为DTO而计算器的方法需要参数(例如, calculateMonthlyPayment(loanAmount,的InterestRate)。这有助于将MortgageCalculator与Mortgage对象分离,但仍然会将Mortgage作为贫血模型。
  2. 将两个类合并为一个“富”MortgageCalculator模型,该模型包含业务逻辑(例如calculateMonthlyPayment)和抵押属性(例如loanAmount)。我的 我担心的是,我不确定是否有必要 calculator对象将其操作数保存为实例变量,但是 他们会促进数据传输,存储和解决贫血吗?
  3. 我想知道理想的方法是什么,或者我是否错过了重点?

3 个答案:

答案 0 :(得分:3)

也许Mortgage对象可以执行部分​​计算。例如,考虑一个计算订单总数的对象:

for (Line line : orderLines)
  int total += line.getPrice() * line.getQuantity();

这称为Feature Envy,可能是:

for (Line line : orderLines)
  int total += line.calculateTotal();

答案 1 :(得分:2)

MortgageCalculator实际上不是域实体,因为它没有填充到数据库中,因此要避免贫血,您可以将逻辑合并到Mortgage实体中:

class Mortgage {
   loanAmount;
   interestRate;

   calculateMonthlyPayment();
}

另一件事:DTO与域实体不同,DTO用于在分发环境中传输数据,而域实体则专注于域逻辑。

您可以将域实体用作DTO,因为在某些情况下,DTO与域实体具有相同的属性。但是,大多数情况下,依赖于每个客户端,他们可能需要获取需要多个域实体的数据。因此,为了分离关注点并使其更易于维护,建议使用域实体创建DTO:

class MortgageDto {
   loanAmount;
   interestRate;
}

答案 2 :(得分:0)

如果您不了解有界情境(BC),则无法进行DDD。那么在这种情况下BC是什么?因为一切都取决于那个。

形成我对你的理解,我认为你有一个MortageCalculator是好的,因为你可以有多种计算抵押贷款的方法。这个类可以有一个与Mortgage论证相关的方法。当然,我所说的可能是错的,因为我不知道你的域名。

如果一个人没有碰巧成为所需领域的专家,那么总是很难回答关于DDD的具体问题。但所有这些都从卑诗省再次开始,你的BC是什么以及抵押贷款的商业角色是什么?