我理解正确吗?如果没有,我将举一个例子。
大致上是。
对于Martin Fowler而言,
领域模型是领域的对象模型,其中包含行为和数据 。
域模型经常与模型相对,在模型中,您有特定的类来承载数据,而其他一些特定的类来承载行为/处理。
如果我参加您的
Income课程,它看起来更像是一个拥有属性/数据的类,而不是具有真实行为的域模型。
public boolean isPositive(){ return amount > 0 ? true : false;}
是一种与模型无关的效用函数。
您可以将其放在
Math课堂上。
我将尝试为您提供一个域模型示例,然后再提供该模型将数据和处理分开的版本。
假设您要建模的应用程序领域的需求中,我们需要为收入增加奖金。例如,此奖金可能发生在圣诞节的冬季(但为什么不参加其他活动)
让域模型对象执行任务,而不是让服务类进行此处理。
Incomes,高级对象可以在
Income实例上进行迭代并应用奖励,我们可以有一个奖励规则类,该规则类根据一些输入值定义奖励。
我介绍了多个类,因为这种想法是允许每个对象根据其职责进行协作。
收入:
public class Incomes { List<Income> incomes = ... .... public void applyBonus(BonusRule bonusRule){ for (Income income : incomes){ income.applyBonus(bonusRule); } }
收入:
public class Income { private float amount;... public void applyBonus(BonusRule bonusRule){ float bonus = bonusRule.compute(this); amount += bonus; } ...}
ChristmasRule:
public class ChristmasBonusRule implements BonusRule {... @Override public float compute(Income income){ float bonus = ... return bonus; } ...}
最后,我们可以通过以下方式进行处理:
void foo(){ // create a domain object that has both behavior and data Incomes incomes = ...; // invoke a functional method on the object by passing another domain object incomes.applyBonus(new ChristmasBonusRule()); }
在将数据和逻辑划分为不同类的设计中,它看起来像这样:
public class IncomeBonusService { // stateless : no incomes data inside it .... public void applyChristmasBonus(List<Income> incomes){ for (Income income : incomes){ // Christmas bonus computation here float bonus = ... income.setAmount(bonus + income.getAmount()); } }}
我们可以这样处理:
// inject the service@AutowiredIncomeBonusService incomeBonusService;void foo(){ // create a domain object that has only data List<Income> incomes = ...; // invoke a service method by passing data as parameter incomeBonusService.applyChristmasBonus(incomes); }
对象没有任何行为(只有getter / setter)的模型设计称为Anemic Domain
Model。
此示例说明的两种方式之间的巨大差异:
领域模型:
对象是有意义的。
在班级之间明确定义了行为责任。
因此具有良好的隔离性,可测试性和可维护性。
例如,添加/删除/单元测试aBonusRule
很容易。对象负责其状态。
的确,由于对象本身可以在与其他对象协作之后更新其状态,因此无需提供设置器。
我们可以在中看到Amount.applyBonus()
:
float bonus = bonusRule.compute(this); amount += bonus;
贫血领域模型:
所有逻辑都在服务类中。
因此,一个地方即可获取代码。
只需几行,就可以了。
但是请注意,这种优势有一定的局限性,因为随着逻辑变得庞大或复杂,最好的事情通常是将逻辑拆分为多个服务类。但是,无论您需要多少服务类,整个逻辑都位于服务类中,而不是其他位置。如果我们将其与可能在某些不同的“类型”类中分解逻辑的领域模型进行比较,则可以简化开发规范。
为域类提供获取/设置程序的必要性。
该域也不负责其状态及其不变规则。
因此,任何依赖域类的类都可以“破坏”其状态。
附带说明一下,默认情况下,某些框架(用于持久性,映射,序列化等)依赖于getter / setter。
这就是为什么这种模型尽管有缺点,但却在某些项目中处于领先地位的原因。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)