领域模型模式示例

2024-03-03

我只是想找一些 Martin Fowler 的例子领域模型 http://martinfowler.com/eaaCatalog/domainModel.html模式,而我不能。

根据我在互联网领域模型上发现的内容,只是向类添加一些“逻辑”方法。例如

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 
}

我理解正确吗?如果没有,我将不胜感激,提供一个领域模型模式使用的小例子。


我理解正确吗?如果没有的话,我将不胜感激 例子。

从广义上讲,是的。

From 马丁·福勒 http://martinfowler.com/eaaCatalog/domainModel.html, 领域模型是包含行为和数据的领域对象模型.
领域模型通常与具有特定类来承载数据和其他一些特定类来承载行为/处理的模型相反。

如果我带你的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);
     }      
}

Income :

public class Income {

  private float amount;
...
  public void applyBonus(BonusRule bonusRule){
       float bonus = bonusRule.compute(this);
       amount += bonus;
  }      
...
}

圣诞节规则:

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)的模型设计称为贫血域模型 https://www.martinfowler.com/bliki/AnemicDomainModel.html.


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

域模型:

  • 对象是有意义的。

  • 班级之间明确定义的行为责任。
    所以具有良好的隔离性、可测试性和可维护性。
    例如,添加/删除/单元测试BonusRule简单。

  • 对其状态负责的对象。
    事实上,不需要提供 setter,因为对象可以在与其他对象协作后自行更新其状态。
    我们可以看到,在Amount.applyBonus() :

    float bonus = bonusRule.compute(this); amount += bonus;

贫血域模型:

  • 所有逻辑都在服务类中。
    所以只有一个地方可以获取代码。
    几行就可以了。
    但请注意,这种优势有一定的限制,因为随着逻辑变得庞大或复杂,最好的办法往往是将逻辑拆分为多个服务类。

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

  • 需要为域类提供 getter/setter。
    该域也不对其状态及其不变规则负责。
    因此任何依赖于域类的类都可以“破坏”其状态。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

领域模型模式示例 的相关文章

随机推荐

  • 如何正确地将 C 程序拆分为文件并包含?

    我组织了我的程序 将每个实体拆分在自己的文件中 是这样的 main c include student h include subject h include classroom h define PI 3 14 int sum int a
  • 将音频从 Android 设备流式传输到另一设备

    我如何通过互联网将音频从一台设备流式传输到另一台设备 我知道使用 Java 套接字发送基本数据 但想知道如何 在文件中途开始流式传输 例如 在歌曲的中间 发送的数据需要什么格式 MediaPlayer可以将url作为数据源 那么音频从服务器
  • 将光标移动到输入字段的开头?

    当您在 Stackoverflow 中点击 提问 时 您会看到一条文字 您的编程问题是什么 请描述一下 我想要同样的事情 我所需要做的就是将光标移动到文本字段的开头 我如何用 jquery 做到这一点 这可能有点过分了 但这些函数对于选择输
  • 从多个因子列生成虚拟矩阵

    我已经在网上搜索过 但没有找到答案 我有一个包含多列的大 data frame 每列都是一个因子变量 我想转换 data frame 使得因子变量的每个可能值都是一个变量 如果该变量存在于因子列中 则该变量包含 1 否则包含 0 这是我的意
  • Random 类线程安全吗?

    共享一个实例是否有效Random多线程之间的类 并打电话nextInt int 特别是来自多个线程 它是线程安全的 因为当多个线程使用时它仍然会生成随机数 Sun Oracle JVM 实现使用synchronized 和AtomicLon
  • 如何使用 Flask 获取页面访问者的 Windows 用户名?

    我到处搜索过 但没有找到任何结果 所以很抱歉 如果这篇文章是骗人的 我找不到任何东西 我为我的公司编写了这个相当广泛的网络应用程序 唯一剩下的就是添加某种审核 我不知道如何捕获当前访问我的页面的人的用户名 由于托管的盒子是以管理员身份登录的
  • 使用 PDFMake 嵌套/子表

    如何在 PDFmake 中使用嵌套 子表 我尝试过简单地放入多个表格 但这不会自动重复顶级表格的标题以进行分页符 此代码是使用子表的简化示例 它改编自 pdfmake Playground 的表格部分 通过 Google 搜索不容易找到 将
  • Djangocms 中的自定义视图?

    我还没有找到令人满意的方法 我有一个运行良好的 djangocms 设置 但我需要将 CMS 外部表格中的内容添加到我的主页 并在模板上呈现该内容 我可以做到这一点 但在 CMS 中编辑 urls py 以使用我的视图 如下所示 url r
  • 我可以使用 conda 安装 Python 的 alpha 或 beta 版本吗?

    在撰写本文时 alpha 版本3 8 0a4python 可用 我想在正式发布之前在 conda 环境中进行一些测试 出于教育目的并满足一些好奇心 当尝试 conda install 3 8 时 我得到了PackagesNotFoundEr
  • 为什么 stylelint vscode 扩展在我的计算机上不起作用?

    我遵循guide https marketplace visualstudio com items itemName stylelint vscode stylelint安装stylelintvscode 扩展 但它在我的电脑上不起作用 我
  • 在R中查找另一个字符串中的一个字符串

    我想在R中的另一个字符串中查找一个字符串 字符串如下 我希望能够将字符串 a 与字符串 b 匹配 输出应该是a b返回 TRUE a lt 6250 7250 6251 b lt 7250 a b FALSE 您可以使用regmatches
  • D3:在多条线的折线图中跳过空值

    我有一个动态数组来显示包含多条线的折线图 例子 var data x 2005 y 100 x 2007 y 96 5 x 2009 y 100 3 x 2011 y 102 3 x 2005 y 100 x 2007 y 105 x 20
  • 通过 PHP 从目录中的文件生成 XML

    我有两个文件夹图像和带照片的大图像 我想生成一个具有两个属性的 XML 文件 如下所示
  • MYSQL 中的字符串连接

    我怎样才能在mysql中连接这个字符串 desc desc desct 我想要的是每次我从 PHP 插入一个变量时 该字符串都会添加到已经在 db 中并用分隔符分隔的字符串中 字段描述应该是这样的 desc 10 30 90 710 假设我
  • 是否会使应用程序不可见?

    我使用了隐式意图 以便在有人单击其他应用程序中的 URL 时打开我的应用程序 我无法看到已部署的应用程序的图标 部署我的应用程序后 如果我返回并尝试找到我的应用程序 我将无法找到它 但它在最近的应用程序中 这是android清单中的代码
  • 为 php 5.6 添加 mongodb 扩展(XAMPP)

    我在这里读过一些关于解决我的问题的帖子 但都不适用于 php 5 6 我下载了php mongo 1 6 8 zip and php mongo 1 6 7 zip并尝试了所有 dll 扩展名 所有扩展名都给出了一个或另一个错误 错误信息
  • 如何为 LLVM IR 生成元数据?

    我正在尝试为我生成的 LLVM IR 生成元数据 我想生成以下形式的元数据 nvvm annotations 0 0 metadata void foo metadata kernel i32 1 其中 foo 是我的 LLVM IR 中的
  • orchard cms:如何将媒体选择器字段添加到自定义部分

    我的问题类似于questions 10369967 orchard cms 如何将媒体选择器字段添加到新模块 https stackoverflow com questions 10369967 orchard cms how to add
  • 我应该在 SharpZipLib 中选择哪种压缩类型?

    我有一个发送文件和文件夹的文件传输应用程序 服务器 客户端 我正在尝试通过 TCP 套接字 发送数据 我已经为传输数据的方式制定了一些规则 因此 如果它发送包含许多文件的大文件夹 则应首先将它们压缩为单个 zip 文件 然后再发送发送的 z
  • 领域模型模式示例

    我只是想找一些 Martin Fowler 的例子领域模型 http martinfowler com eaaCatalog domainModel html模式 而我不能 根据我在互联网领域模型上发现的内容 只是向类添加一些 逻辑 方法