我正在制作一个应用程序,试图坚持 DDD 概念和实践。我有一个丰富的领域模型,其中包含实体、值对象、封装在其中的业务规则等。
实体实际上并没有太多字段,并且在包含数据时相对较小,但问题是,其中一些实体变得非常大(如:表示它们的类),因为与这些实体有很多可能的交互。
你知道,
void DoThis();
int GetThat();
bool CheckForThis();
与我的域的某些部分的每次交互都由公共或内部方法表示,每个方法都包含一些业务规则。
我尝试将该逻辑提取到我称之为策略的内部类中,所以而不是
public int CalculateAmountOfCoolThingy()
{
int result = 0;
/*
Super duper complicated calculations here with 100 lines of code.
*/
return result;
}
在我的实体中,我有:
internal sealed class CoolThingyCalculationPolicy
{
public int CalculateAmountOfCoolThingy(MyEntity entity)
{
int result = 0;
/*
Super duper complicated calculations here with 100 lines of code.
*/
return result;
}
}
在我的实体中:
public int CalculateAmountOfCoolThingy()
{
CoolThingyCalculationPolicy policy = new CoolThingyCalculationPolicy();
int result = policy.CalculateAmountOfCoolThingy(this);
return result;
}
是这样吗?这是一个好的做法吗?因为感觉不太对劲。也许有更好的方法?
是的,您可以将这些规则封装在另一个名为域服务的类中。但请记住,您必须将服务注入到您的域模型中。
您应该考虑设计的三个属性。域的纯度、完整性和性能。你不能同时拥有这一切。
在这篇文章中,Vladimir Khorikov 谈到了这三个,我建议你仔细阅读它。在结论中,他建议域纯度比完整性更重要(您可以在文章中阅读原因)。所以我建议:
另一件需要考虑的事情是,除非有充分的理由,否则不建议将逻辑移动到域服务。胖域服务意味着瘦域模型,这会导致域模型贫乏。为了更好地管理领域模型,请考虑将它们分成更小的构建块,例如实体和值对象。使用领域服务来制作较小的模型感觉就像作弊。因为责任应该在域模型上,并且您将其强制到另一个对象中。除非您想重用某些逻辑或计算,否则这不是创建领域服务的好理由。