域模型模式示例 [英] Domain Model pattern example

查看:79
本文介绍了域模型模式示例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试查找Martin Fowler的域模型模式的一些示例,我可以没错

I'm just trying to find some examples of Martin Fowler's Domain Model pattern and I can't.

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

From what I found on the Internet Domain Model is just adding some "logic" methods to classes. For example

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我理解正确吗?如果没有,我将为您提供一些域模型模式用法示例。

Did I understand it correctly? If not, I'd be grateful for a little example of Domain Model Pattern usage.

推荐答案


我理解正确吗?如果不是这样,我将不胜感激,举例说明

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

广泛地说,是的。

来自马丁·福勒域模型是包含行为和数据的域的对象模型。

域模型经常与具有特定类来承载数据和某些其他特定类的模型相对承担行为/处理。

From Martin Fowler, domain model is an object model of the domain that incorporates both behavior and data.
The domain model is frequently opposed to a model where you have specific classes to bear data and some other specific classes to bear behavior/processings.

如果我接受您的收入类,则它看起来更像是一个包含属性/数据而不是域的类具有真实行为的模型。

If I take your Income class, it looks like more as a class that holds properties/data than an domain model with a real behavior.

public boolean isPositive(){
   return amount > 0 ? true : false;
}

是一种与模型无关的效用函数。

您可以将其放在 Math 类中。

is a kind of utility function that has no relation with the model.
You could put that in a Math class.

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

I will try to give you a domain model example and then the version where the model separates data and processing.

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

Suppose in the requirements of the domain of the application you are modeling, we need to add a bonus for incomes. This bonus may take place in winter for Christmas for example (but why not for other events)

我们让域模型对象代替了服务类来进行此处理执行任务。

Rather than having a service class to do this processing, we let domain model objects perform the task.

收入,高级对象可能会在收入实例并应用奖励,我们可以有一个奖励规则类,该规则类根据一些输入值定义奖励。

我引入了多个类,因为这种想法是允许每个对象根据其职责进行协作。

Incomes, a high level object could iterate on Income instances and apply the bonus and we could have a bonus rule class that defines the bonus according to some input values.
I introduce multiple classes since the idea is to allow each objects to collaborate according to their responsibilities.

收入:

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:

ChristmasRule :

public class ChristmasBonusRule implements BonusRule {
...
  @Override
  public float compute(Income income){
       float bonus = ...
       return bonus;  
  }      
...
}

最后,我们可以通过以下方式应用处理:

And finally, we could apply the processing in this way :

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()); 
}

在设计中,您将数据和逻辑分离到不同的类中,看起来像这样:

In a design where you separate data and logic in distinct classes, it could look like more like that :

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());
     }
  }
}

我们可以应用该处理这样:

And we could apply the processing in this way :

// 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域模型

A model design where the objects have no behavior (only getter/setter) is called Anemic Domain Model.

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

Big differences between the two ways illustrated by this example :

域模型:


  • 对象是有意义的。

  • The objects are meaningful.

在类之间定义了行为责任。

如此良好的隔离性,可测试性和可维护性。

例如,添加/删除/单元测试 BonusRule 很容易。

Behavioral responsibility finely defined between classes.
So good isolation, testability and maintainability.
For example, adding/removing/unit-testing a BonusRule is easy.

负责状态的对象。

实际上,无需提供设置器,因为对象可以在与其他对象协作后自行更新其状态。

我们可以在 Amount.applyBonus()中看到:

Objects responsible of their state.
Indeed, no need to provide setters as the object can itself update its state after collaborating with other objects.
We could see that in Amount.applyBonus() :

float bonus = bonusRule.compute(this);
金额+ =奖金;

贫民区模型:


  • 所有逻辑都在服务类中。

    因此,一个地方即可获取代码。

    只需几行就可以了。

    但是请注意,这种优势有一定的局限性,因为随着逻辑变得庞大或复杂,最好的事情通常是将逻辑拆分为多个服务类。

  • All the logic is in the service class.
    So a single place to get the code.
    With few lines, it is fine.
    But note that this advantage has a certain limit because as the logic becomes big or complex, the best thing is often splitting the logic in multiple service classes.

但是,无论您需要多少服务类,整个逻辑都位于服务类中,而不是其他任何地方。如果将其与可能在某些不同类中分解逻辑的领域模型进行比较,则可以简化开发规范。

But whatever the number of Service classes you need, the whole logic is located in the service classes and not somewhere else. Which may ease development norms if we compare it to the domain model where the logic may be exploded in some different "types" of classes.

为域类提供getter / setter的必要性。

域也不负责其状态和不变规则。< br>
因此,依赖域类的任何类都可以破坏其状态。

Necessity to provide getter/setter for domain classes.
The domain is not responsible of its state and its invariant rules either.
So any class that depends on the domain class can "break" its state.

另外,默认情况下,某些框架(用于持久性,映射,序列化等)依赖于getter / setter。

这就是为什么该模型尽管有缺点,但却在某些项目中处于领先地位。

As a side note, some frameworks (for persistence, mapping, serialization, ...) rely by default on getter/setter.
That's why this model, despite its drawbacks, leads in some projects.

这篇关于域模型模式示例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆