在我工作的地方,我们已经就这个问题反复讨论过很多次,并正在寻求健全性检查。这是问题:业务对象应该是数据容器(更像是 DTO),还是还应该包含可以在该对象上执行某些功能的逻辑。

示例 - 以一个客户对象为例,它可能包含一些常见属性(名称、Id 等),该客户对象是否还应该包含功能(保存、计算等)?

一种推理是,将对象与功能分离(单一责任主体),并将功能放入业务逻辑层或对象中。

另一种推理是,不,如果我有一个客户对象,我只想调用 Customer.Save 并完成它。如果我正在消费该对象,为什么我需要知道如何拯救客户?

我们的最后两个项目已将对象与功能分离,但在新项目上再次引发了争论。哪个更有意义?

编辑

这些结果与我们的辩论非常相似。投向某一方或另一方的一票完全改变了方向。还有人想加 2 美分吗?

编辑

尽管答案样本很小,但大多数人似乎认为业务对象中的功能只要简单就可以接受,但持久性最好放置在单独的类/层中。我们会尝试一下。感谢大家的意见...

有帮助吗?

解决方案

对象是状态和行为在一起。如果一个对象有理智的行为(例如,计算年龄的人从他们的出生日期或发票总税收),通过各种手段添加。业务对象是无非的DTO被称为一个“贫血的领域模型”。我不认为这是一个设计要求。

持久性是一种特殊的行为。什么我打电话“懂事”是企业的行为。业务对象不需要知道它的持久性。我想说,一个DAO可以保持持久性分开的商业行为。我没有在“合理”范畴把“保存”。

其他提示

业务对象 可以有 业务功能.

持久性不是业务功能 ,而是技术实现。

长话短说:

  1. 保存/更新/删除/查找等 - 远离持久层中的业务对象。
  2. CalculateSalary、ApplyDiscount 等是与业务相关的方法,可以是:
    1. 业务对象的方法 (因此 BO 是实体的自包含表示)或;
    2. 单独的服务 实现特定的功能(因此 BO 的行为更像是 DTO)。

至于第2点。
我应该提到,方法 2.1 往往会使 BO 过于臃肿,并且 违反建议零售价. 。而2.2引入了更多的维护 复杂.

我通常 平衡 在 2.1 和 2.2 之间,以便我将与数据相关的琐碎事情放入 Business Objects 中,并为更复杂的场景创建服务(如果有超过 4 行代码 - 使其成为一个服务)。

这将业务对象的范式转变为更多的数据传输对象。

但这一切都使得项目更容易开发、测试和维护。

无论平台或语言如何,答案都是相同的。这个问题的关键是一个对象是否应该能够 自主性 或者将任何给定的行为分散到具有更多行为的对象中是否更好 集中责任.

对于每个班级,答案可能不同。我们最终得到了一个范围,我们可以根据该范围来安排课程 责任密度.

                          (Level of responsibility for behavior)
         Autonomy - - - - - - - - - - - - - - - - - - - Dependence  
      High
  C      -   <<GOD object>>                            <<Spaghetti code>>
  l      -
  a      -  
  s      -                                      
  s      -                 
         -                        
  s      -  
  i      -  
  z      -
  e      -  <<Template>>                                <<Framework>>
       low  

假设您赞成让班级自行执行所有行为,或者尽可能多地执行。从该图的左侧开始,当您使类更加自治时,类的大小将会增长,除非您不断重构它以使其更加通用。这导致了 模板. 。如果不进行重构,类就会变得更加“上帝喜欢“因为如果它需要某种行为,它就会有一个方法。领域和方法的数量不断增加,很快就变得难以管理和不可避免。由于该类已经做了很多事情,程序员宁愿增加这个怪物,也不愿试图将其拆散并解决问题。

图右侧的类在很大程度上依赖于其他类。如果依赖级别很高但单个类很小,则表明存在 框架;每个类的作用并不大,并且需要大量依赖类来完成某些功能。另一方面,一个高度依赖的类也有大量的代码,这表明该类充满了 意大利细面条.

这个问题的关键是确定您在图表上感觉更舒服的位置。无论如何,除非应用某种组织原则,否则各个类最终都会分散在图表上,这就是您如何实现以下结果的方法: 模板 或者 框架.

刚刚写完这篇文章后,我想说班级规模和组织程度之间存在相关性。罗伯特·C.Martin(或“Bob 叔叔”)在他关于包依赖性的非常详尽的论文中涵盖了类似的基础 设计原则和设计模式. J依赖 是第 26 页图表背后想法的实现和补充 静态分析工具 例如 格子风格PMD.

我觉得它更有意义的业务对象知道如何“处理”自己,那么将不得不把这一负担系统的其它部分。在你的榜样,最合理的地方来处理如何“拯救”客户数据会是这样,对我来说,在客户对象。

这可能是因为我考虑数据库是“数据容器”,所以我赞成“业务对象”的很是保护从直接访问数据容器和执行标准的“业务规则”有关的更高级别该数据是如何被访问/操纵。

我们已经使用洛基Lhotka的CSLA框架多年,喜欢它的设计方式。在此框架内的所有功能都包含在对象。虽然我可以看到separting逻辑出来的价值,我不认为我们会从这一理念很快切换了。

的业务对象应为约封装数据和由该对象建模的业务实体相关联的行为。想想看这样的:面向对象编程的主要原则之一是对数据封装的数据和相关的行为。

持久性不是建模对象的行为。我发现开发的进展更顺利,如果业务对象是持久性ignornant。开发新的代码和单元测试的新代码更快速地发生,如果业务对象并不特别依赖于底层的管道更顺畅。这是因为我可以嘲笑这些方面,而忘记了不必经过箍去的数据库,等等。我的单元测试可以更快的速度执行(如果你有成千上万的自动化测试一个巨大的加与每个版本运行)和我将有更小的压力,因为我不会有测试,因为数据库连接问题失败(伟大的,如果你经常脱机工作或远程,不能随时访问你的数据库哦,顺便说一下,这些方面(数据库连接等)应在别处测试!)。

  

推理的其他行说,没有,如果我有一个客户对象我只是想打电话Customer.Save,并用它做。为什么我需要知道如何保存客户,如果我消费对象?

明知Customer具有Save方法已经知道如何保存一个客户对象。你有没有在你的业务对象嵌入该逻辑回避的问题。相反,你做了你的代码库更加紧密耦合,因此难以维护和测试。推离坚持对象给别人的责任。

在业务对象,因为它们被命名,显然应该coutain自己的业务逻辑,该领域在服务层是中间业务逻辑的动态。

在另一侧上,可以在BO是一个数据容器(DTO?)组合物和方法;这意味着BO是纯functionnal?这可能避免所有BO和DTO之间的转换。

在MVC架构,

我们可以说,模型包含的业务对象。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top