Language agnostic 业务对象-容器还是功能?

Language agnostic 业务对象-容器还是功能?,language-agnostic,business-objects,data-transfer-objects,Language Agnostic,Business Objects,Data Transfer Objects,在我工作的地方,我们已经在这个问题上来回奔波了好几次,并且正在寻找一个理智的检查。这里有一个问题:业务对象应该是数据容器(更像DTO),还是还应该包含可以在该对象上执行某些功能的逻辑 示例-以客户对象为例,它可能包含一些公共属性(名称、Id等),该客户对象是否还包括函数(保存、计算等) 一种推理方式是将对象与功能(单一责任主体)分离,并将功能放在业务逻辑层或对象中 另一种推理是,不,如果我有一个customer对象,我只想打电话给customer。保存并处理它。如果我正在消费物品,为什么我需要知

在我工作的地方,我们已经在这个问题上来回奔波了好几次,并且正在寻找一个理智的检查。这里有一个问题:业务对象应该是数据容器(更像DTO),还是还应该包含可以在该对象上执行某些功能的逻辑

示例-以客户对象为例,它可能包含一些公共属性(名称、Id等),该客户对象是否还包括函数(保存、计算等)

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

另一种推理是,不,如果我有一个customer对象,我只想打电话给customer。保存并处理它。如果我正在消费物品,为什么我需要知道如何拯救客户

我们的前两个项目将对象与功能分开,但是关于一个新项目的争论再次被提出。哪个更有意义

编辑

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

编辑


尽管答案抽样很小,但似乎大多数人认为业务对象中的功能是可以接受的,只要它简单,但持久性最好放在单独的类/层中。我们试试看。感谢大家的投入……

我认为,业务对象应该知道如何“处理”自己,然后将负担放到系统的其他地方。在您的示例中,对我来说,处理如何“保存”客户数据的最合理的位置是customer对象


这可能是因为我认为数据库是“数据容器”,所以我赞成“业务对象”是保护数据容器不受直接访问的更高级别,并强制标准的“业务规则”如何访问/操纵数据。

对象是状态和行为。如果一个对象有合理的行为(例如,从出生日期开始计算一个人的年龄,或一张发票的总税额),请务必添加该对象。仅仅是DTO的业务对象被称为“贫乏的域模型”。我不认为这是设计需求


坚持是一种特殊的行为。我所说的“明智”是商业行为。业务对象不需要知道它是持久的。我认为DAO可以将持久性与业务行为分开。我没有将“保存”放在“合理”类别中。

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

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

长话短说:

  • 保存/更新/删除/查找等-远离持久层中的业务对象
  • CalculateSalary、ApplyDiscount等是与业务相关的方法,可以是:
  • 业务对象的方法(因此BO是实体的自包含表示)或
  • 实现特定功能的独立服务(因此BO的行为更像DTO)
  • 至于第2点。
    我应该提到的是,方法2.1往往会使BO过于臃肿,违反SRP。而2.2引入了更多的维护复杂性

    我通常将
    平衡在2.1和2.2之间,以便将与数据相关的琐碎事情放入业务对象中,并为更复杂的场景创建服务(如果有超过4行代码,则将其作为服务)

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


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

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

    持久性不是建模对象的行为。我发现,如果业务对象不考虑持久性,开发过程会更加顺利。如果业务对象没有特别绑定到底层管道,那么开发新代码和单元测试新代码的速度会更快、更流畅。这是因为我可以模拟这些方面,并且忘记了必须通过循环才能到达数据库等。我的单元测试将执行得更快(如果每个构建都运行数千个自动化测试,这将是一个巨大的优势),而且我的压力会更小,因为我不会因为数据库连接问题而让测试失败(如果您经常脱机或远程工作,并且不能始终访问您的数据库,那就太好了。哦,顺便说一句,这些方面(数据库连接等)应该在别处测试!)

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


    知道
    Customer
    有一个
    Save
    方法就是知道如何保存Customer对象。将该逻辑嵌入到业务对象中并没有避免这个问题。相反,您使您的代码库更紧密地耦合在一起,因此更难维护和测试。推卸维护obj的责任无论平台或语言如何,答案都是一样的。这个问题的关键是一个对象是否应该具有自主性,或者任何给定的行为是否最好在责任更为集中的对象之间传播

                              (Level of responsibility for behavior)
             Autonomy - - - - - - - - - - - - - - - - - - - Dependence  
          High
      C      -   <<GOD object>>                            <<Spaghetti code>>
      l      -
      a      -  
      s      -                                      
      s      -                 
             -                        
      s      -  
      i      -  
      z      -
      e      -  <<Template>>                                <<Framework>>
           low  
    
    每个班级的答案可能不同