贫血领域模型:优点/缺点

2023-11-24

我想知道使用贫血域模型的优点和缺点(请参阅下面的链接)。

福勒文章


由于“贫血领域模型”是反模式,为什么有这么多系统实现它?

我认为有几个原因

1.系统的复杂性

在一个简单的系统中(几乎是您在互联网上找到的所有示例和示例代码)如果我想实现:

将产品添加到订单

我把这个功能放在订单上

public void Order.AddOrderLine(Product product)
{
    OrderLines.Add(new OrderLine(product));
}

很好而且超级面向对象。

现在假设我需要确保我需要验证产品是否存在于库存中,如果不存在则抛出异常。

我不能再将其放在订单上,因为我不希望我的订单依赖于库存,所以现在需要将其放在服务上

public void OrderService.AddOrderLine(Order order, Product product)
{
    if (!InventoryService.Has(product)
       throw new AddProductException

    order.AddOrderLine(product);
}

我还可以将 IInventoryService 传递给 Order.AddOrderLine,这是另一种选择,但这仍然使 Order 依赖于 InventoryService。

Order.AddOrderLine 中仍然有一些功能,但通常仅限于订单范围,而根据我的经验,有更多的业务逻辑超出订单范围。

当系统不仅仅是基本的 CRUD 时,您最终将在 OrderService 中得到大部分逻辑,而在 Order 中得到很少的逻辑。

2. 开发者对OOP的看法

互联网上有很多关于实体应该采用哪种逻辑的热烈讨论。

就像是

订单.保存

秩序是否应该知道如何拯救自己?假设我们有相应的存储库。

现在订单可以添加订单行吗?如果我尝试用简单的英语来理解它,它也没有真正的意义。用户将产品添加到订单中,那么我们应该执行 User.AddOrderLineToOrder() 吗?这似乎太过分了。

OrderService.AddOrderLine() 怎么样。现在有点道理了!

我对 OOP 的理解是,为了封装,您将函数放在类上,该函数需要访问类的内部状态。如果我需要访问 Order.OrderLines 集合,我会将 Order.AddOrderLine() 放在 Order 上。这样类的内部状态就不会暴露。

3. IoC容器

使用 IoC 容器的系统通常都很贫乏。

这是因为您可以测试具有接口的服务/存储库,但无法(轻松)测试域对象,除非您将接口放在所有这些对象上。

由于“IoC”目前被誉为解决所有编程问题的解决方案,因此很多人盲目遵循它,这种方式最终导致贫血领域模型。

4. 面向对象编程很难,过程化很容易

我有一点“知识的诅咒“关于这一点,但我发现 对于新开发人员来说,拥有 DTO 和服务比 Rich Domain 容易得多。

可能是因为使用 Rich Domain,更难知道将逻辑放在哪些类上。什么时候创建新类?使用哪些模式? ETC..

对于无状态服务,您只需将其放入名称最接近的服务中即可。

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

贫血领域模型:优点/缺点 的相关文章

  • 策略、访问者和模板方法模式之间有什么区别?

    我在课堂上刚刚学习了这些设计模式 但是我看不出它们之间有什么区别 它们听起来是一样的 都是在抽象类之上创建具体类 有人可以帮我打消这个疑虑吗 谢谢 访问者 策略和模板模式都包含算法的应用 最大的区别在于它们是如何被唤起以及如何在实践中使用的
  • 为什么以及如何避免事件处理程序内存泄漏?

    通过阅读 StackOverflow 上的一些问题和答案 我刚刚意识到 使用以下命令添加事件处理程序 在 C 或者我猜 其他 net 语言 中可能会导致常见的内存泄漏 我过去多次使用过这样的事件处理程序 但从未意识到它们可能会导致或已经导致
  • 如何在javascript中实现观察者模式?

    你好 我正在尝试在 JavaScript 中实现观察者模式 我的index js document ready function var ironMan new Movie ironMan setTitle IronMan ironMan
  • 全局常量是反模式吗?

    我一直认为仅仅为了保持常量而创建一个类是一个糟糕的设计 但最近 我尝试用谷歌搜索它 发现只有一个界面作为常量是不好的反模式 没有提到使用一类常量 我认为 由于常量类实际上与全局变量没有太大区别 这就是我反对它并倾向于重构此类类的原因 它创建
  • 根据维基百科,为什么“call super”被视为反模式? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 通过反思思考工厂设计模式

    我正在对工厂模式进行研发 我开发了下面的代码 现在我知道子类是 Dog 和 Cat 但是如果我想通过在 main 中传递类名来通过反射实现同样的事情 请告诉我该怎么做 爪哇 public abstract class Animal publ
  • 极小极大算法

    我有一个关于 Minimax 算法的简单问题 例如 对于 tic tac toe 游戏 如何确定每个玩家玩的效用函数 它不会自动执行此操作 是吗 我必须对游戏中的值进行硬编码 它无法自己学习它们 不是吗 不 MiniMax 不会学习 它是暴
  • 是否有加权水库采样的算法? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 当数据流中的点具有相关权重时 是否有一种算法可以执行水库采样 Pavlos Efraimidis 和 Paul Spirakis 的算
  • 将古吉拉特语文本插入 MySQL 表会产生垃圾字符和不可读的文本

    我有三个 MySQL 表 我正在向其中插入古吉拉特语内容 当我插入两个表时 它们插入得很好并且可读 但在一个表中 它显示垃圾字符 不可读的文本 我怎样才能解决这个问题 MySQL 有每个表的字符集设置 http dev mysql com
  • 访客模式如何不违反开放/封闭原则?

    来自维基百科 这个想法是 一旦完成 类的实现只能修改为 纠正错误 新的或更改的功能将需要创建不同的类 该类可以通过继承重用原始类的代码 据我了解 访问者模式是一种强大的技术 可以通过使用双重分派来遍历实现相同接口的相似但不同的对象 在我的一
  • 用于将 cython 中的许多 C++ 类包装到单个共享对象的项目结构

    我在文档 邮件列表和这个问题在这里 https stackoverflow com questions 10300660 cython and distutils 但我想得到一个更直接的答案来解决我的具体情况 我正在通过尝试一点一点地包装我
  • DCI - 数据、上下文和交互 - MVC 的继承者?

    最好的描述是什么数据 上下文和交互 DCI http www gertrudandcope com a googlepages com thedciarchitecture将其推销给组织 它的创建者是特里格夫 雷恩斯考格 http folk
  • 语义差异实用程序[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在尝试找到一些语义差异 合并实用程序的好例子 比较源代码文件的传统范例是通过比较行和字符来工作的
  • 查找字符串中最常见的子字符串的算法

    是否有任何算法可用于查找字符串中最常见的短语 或子字符串 例如 以下字符串将 hello world 作为其最常见的两个单词短语 hello world this is hello world hello world repeats thr
  • 设计模式和库有什么区别?

    设计模式和库有什么区别 我似乎找不到任何地方的区别 DesingPatterns 被认为是通过解决已知问题来帮助开发人员 例如 ObserverPattern 用于观察concreate 对象并执行特定操作 mediator 用于集中应用程
  • Java中的对象池模式

    所以我实现了自己的对象池模式 它工作得很好并且符合预期 从列表中返回我的 老师 对象 并在没有对象时创建它们 我的问题 返回的对象 Teacher 然后需要被转换为它的专门子类之一 例如 生物老师 获得这种功能的最佳方法是什么 编辑 抱歉
  • StockTrader RI > 控制器、演示者,WTF?

    我目前正在学习如何通过 Prism 复合 WPF 项目高级使用 WPF 我观看了很多视频和示例 演示应用程序 StockTraderRI 让我提出了这个问题 以下各部分的具体作用是什么 SomethingService 好的 这是管理数据的
  • 在爬行或使用 nutch 和 solr 建立索引期间从 html 中删除菜单

    我正在使用 nutch 爬行我们的大型网站 然后使用 solr 进行索引 结果非常好 然而 网站上有几个菜单结构会索引并破坏查询结果 每个菜单都在 DIV 中明确定义 因此 div div or div div 和其他几个 我需要在某个时候
  • 什么是日历队列?

    我正在致力于构建一个离散事件模拟器 维基百科提到有几种通用优先级队列非常适合在 DES 中使用 具体来说 它提到日历队列是一个很好的结构 我找到了一份 pdf 1988 年的 其中提到了日历队列 但在大多数情况下我找不到关于它们的任何其他内
  • 我应该测试是否等于 1 还是不等于 0?

    前几天我在这里编码 写了几个 if 语句 其中的整数总是要么0 or 1 实际上充当bools 我问自己 当检测结果呈阳性时 哪个更好 测试int 1 or int 0 例如 给定一个 intn 如果我想测试是否是true 我应该使用n 1

随机推荐

  • 有人可以建议一个测试自动化工具来自动化 Java applet 窗口吗?

    有人可以建议一个测试自动化工具来自动化 Java applet 窗口吗 也需要它来识别小程序窗口中的各种按钮 我强烈推荐FEST用于所有功能性 Java GUI 测试 并且它支持小程序
  • 计算文本 OpenCV 的倾斜

    我正在尝试计算图像中文本的倾斜 以便我可以纠正它以获得最佳的 OCR 结果 目前这是我正在使用的功能 double compute skew Mat img Binarize cv threshold img img 225 255 cv
  • python如何将css文件解析为键值[关闭]

    Closed 这个问题不符合堆栈溢出指南 目前不接受答案 我有一个像这样的CSS body html aaa aaa h1 h2 bbb bbb h3 h4 h5 ccc ccc 我想解析这个字符串并获得一个有序的字典 或类似的东西 bod
  • 使用 apache poi 读取 xlsx 时主线程中出现 NoSuchMethodError

    我的代码是 import org apache poi poifs filesystem POIFSFileSystem import org apache poi ss usermodel Workbook import org apac
  • 使用c#删除活动目录中的用户

    我已经编写了一些代码 但不起作用 它抛出异常 发生操作错误 代码 gt DirectoryEntry dirEntry new DirectoryEntry LDAP path admin username admin password d
  • GridView - 使用 CSS 友好的控制适配器删除 EmptyDataTemplate 和 EmptyDataText

    正如问题中指出的 EmptyDataTemplate 和 EmptyDataText 在 GridView 中不起作用 using CSS 友好的控制适配器删除将由 EmptyDataTemplate 填充或在 GridView 中的 Em
  • appfuse 与 roo - 你会使用什么

    Appfuse 与 Roo 您会使用什么以及为什么 各自的优点是什么 根据我给的答案服务器端线程在这个问题上 AppFuse 旨在为您的新项目提供单一的初始支架 这与 Maven 原型或 Eclipse 的 新项目 功能类似 您可以在新项目
  • OSError 故障排除:pty 设备不足

    有时 我在调用时会收到 OSError 异常 并显示消息 out of pty devices pty openpty 当我的脚本的一堆实例同时运行时就会发生这种情况 我达到的极限是什么 我该如何解决这个问题 CentOS 5 6 Pyth
  • 用CSS生成箭头线[重复]

    这个问题在这里已经有答案了 我正在尝试生成一条水平直线 中间有一个细分以显示箭头 这个想法是 该行下方显示的内容将提供有关该行上方显示的内容的详细信息 该行应如下所示 我正在尝试使用纯 HTML 和 CSS 无位图图像 生成它 用于字体真棒
  • 如何绕过 Linux“太多参数”限制

    我必须将 256Kb 的文本作为参数传递给 aws sqs 命令 但在命令行中遇到了大约 140Kb 的限制 这个问题在很多地方都有讨论过自 2 6 23 内核起 该问题已在 Linux 内核中解决 但无法让它发挥作用 我在用3 14 48
  • 如何更改默认分支以推送到 Mercurial 中?

    我喜欢在 Mercurial 中创建命名分支来处理可能需要一段时间编码的功能 所以当我推送时我会执行hg push r default确保我只将更改推送到默认分支 然而 必须记住的是一种痛苦 r default每次我执行推送或传出命令时 所
  • @Temporal(TemporalType.DATE) 与 Oracle 12

    在我们的数据库中 我们有多个带有日期字段的实体 Oracle 将每个日期视为相同的 包含日期和时间部分 然而 JPA 实体通过注释 Temporal 进行区分 当我们想省略时间部分时 我们用 Temporal TemporalType DA
  • 在alertDialog中验证EditText

    我正在尝试添加空字段验证EditText on AlertDialog 但即使字段为空后 也不会显示错误消息 而是AlertDialog正在关闭 但是 如果条件运行良好 因为如果任何字段为空 我将无法进行后期操作 这是我的 Java 示例代
  • 如何使用返回的 linq 变量?

    我决定快速了解一下 LINQ 方面的内容 而不是仅仅使用直接的 foreach 循环 但我在让它工作时遇到了一些麻烦 主要是由于我认为的数据类型 到目前为止 我已经得到了这个 var selectedSiteType from sites
  • 页面的官方 Facebook RSS 提要

    许多人已经描述了如何获取 Facebook 页面的 RSS 数据源 例如 http ahrengot com tutorials facebook rss feed 以下 URL 提供了可口可乐页面的 feed 但是 我似乎无法在 face
  • 在 Web 应用程序之间共享 ASP.NET 资源文件

    我有多个项目需要共享资源文件 resx 已提出将资源文件移动到单独的程序集并让 Web 项目引用它的建议 有如何执行此操作的示例吗 我是否创建一个新的类库项目并将 App GlobalResource 文件夹移到其中 我认为这不会起作用 因
  • 如何使用自然的entrySet()顺序迭代HashMap?

    我的地图包含按字母顺序排序的键 当我显示它时 我使用的是entrySet iterator 但我的结果不是按字母顺序排列的 我如何才能按顺序获得结果 不 您的地图不按字母顺序保存元素 你可能有 put 然后按该顺序 但映射没有定义的迭代顺序
  • 您的 Android App Bundle 使用错误的密钥进行签名。确保您的应用程序包使用正确的签名密钥进行签名,然后重试

    如何使用正确的签名密钥对我的 Android 应用程序包进行签名 我为这个问题把头撞在桌子上大约两个小时 当我最终放弃并填写 重置密钥 请求时 我意识到我当前正在尝试将其上传到错误的项目一直以来 因此 第一步 确认您正在尝试上传到正确的项目
  • 流式 HTTP 响应,刷新到浏览器

    我有如下的观点 from django views decorators http import condition def stream for i in range 0 40 yield 1024 yield d i time slee
  • 贫血领域模型:优点/缺点

    我想知道使用贫血域模型的优点和缺点 请参阅下面的链接 福勒文章 由于 贫血领域模型 是反模式 为什么有这么多系统实现它 我认为有几个原因 1 系统的复杂性 在一个简单的系统中 几乎是您在互联网上找到的所有示例和示例代码 如果我想实现 将产品