gpt4 book ai didi

java - 域模型模式示例

转载 作者:行者123 更新时间:2023-12-01 09:43:57 25 4
gpt4 key购买 nike

我只是想查找Martin Fowler的Domain Model模式的一些示例,但我找不到。

从我在Internet Domain Model上发现的内容来看,只是在类中添加了一些“逻辑”方法。例如

public class Income {
private String title;
private String comment;
private String date;
private Double amount;
private Integer category;

public ExIn(String title, String comment, Double amount, Integer category, String date) {
this.title = title;
this.comment = comment;
this.date = date;
this.amount = amount;
this.category = category;
}

public Integer getCategory() {
return category;
}

public void setCategory(Integer category) {
this.category = category;
}

// more getters and setters
// Domain Model part starts
public boolean isPositive()
{
return amount > 0 ? true : false;
}
// more methods like that
}

我理解正确吗?如果不是这样,我将不胜感激地举一个域模型模式用法的小例子。

最佳答案

Did I understand it correctly? If not, I'd be grateful for a little example.



广泛来说,是的。

Martin Fowler开始, 域模型是该域的对象模型,该模型既包含行为又包含数据
域模型经常与模型相对,在模型中,您有特定的类来承载数据,而其他一些特定的类来承载行为/处理。

如果我使用 Income类,则它看起来更像是一个包含属性/数据的类,而不是具有实际行为的域模型。
public boolean isPositive(){
return amount > 0 ? true : false;
}

是一种与模型无关的效用函数。
您可以将其放在 Math类中。

我将尝试为您提供一个域模型示例,然后再提供该模型将数据和处理分开的版本。

假设您要建模的应用程序领域的需求中,我们需要为收入增加奖金。例如,这个奖金可能发生在圣诞节的冬天(但是为什么不参加其他 Activity )

让域模型对象执行任务,而不是让服务类进行此处理。
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
@Autowired
IncomeBonusService 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

此示例说明的两种方式之间的巨大差异:

领域模型:
  • 对象是有意义的。
  • 在类之间很好地定义了行为责任。
    因此具有良好的隔离性,可测试性和可维护性。
    例如,添加/删除/单元测试BonusRule很容易。
  • 负责其状态的对象。
    的确,由于对象本身可以在与其他对象协作之后更新其状态,因此无需提供 setter 。
    我们可以在Amount.applyBonus()中看到:
    float bonus = bonusRule.compute(this);
    amount += bonus;

  • 贫血领域模型:
  • 所有逻辑都在服务类中。
    因此,一个地方即可获取代码。
    用几行就可以了。
    但是请注意,这种优势有一定的局限性,因为随着逻辑变得庞大或复杂,最好的事情通常是将逻辑拆分为多个服务类。
  • 但是,无论您需要多少服务类,整个逻辑都位于服务类中,而不是其他位置。如果我们将其与可能在某些不同的“类型”类中分解逻辑的领域模型进行比较,这可能会简化开发规范。
  • 必须为域类提供getter/setter。
    该域也不负责其状态及其不变规则。
    因此,任何依赖于域类的类都可以“破坏”其状态。

  • 附带说明一下,默认情况下,某些框架(用于持久性,映射,序列化等)依赖于getter/setter。
    这就是为什么该模型尽管有缺点,但却在某些项目中处于领先地位的原因。

    关于java - 域模型模式示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41335249/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com