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

发布于 2024-08-13 05:10:09 字数 1431 浏览 10 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

夢归不見 2024-08-20 05:10:09

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

坚持是一种特殊的行为。我所说的“明智”是商业行为。业务对象不需要知道它是持久的。我想说 DAO 可以将持久性与业务行为分开。我不会将“保存”归入“明智”类别。

Objects are state and behavior together. If an object has sensible behavior (e.g., calculating age for a Person from their birth date, or a total tax for an Invoice), by all means add it. Business objects that are nothing more than DTOs are termed an "anemic domain model." I don't think it's a design requirement.

Persistence is a special kind of behavior. What I'm calling "sensible" is business behavior. A business object need not know that it's persistent. I'd say that a DAO can keep persistence separate from business behavior. I don't put "save" in the "sensible" category.

孤独难免 2024-08-20 05:10:09

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

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

长话短说:

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

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

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

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

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

Business objects CAN have business functionality.

Persistence is not a business functionality , but is technical implementation.

Long story short:

  1. Save/Update/Delete/Find etc - keep away from the business objects in a persistence layer.
  2. CalculateSalary, ApplyDiscount etc are business related methods and can be:
    1. methods of the business objects (so BO is self contained representation of entity) or;
    2. separate services implementing particular functionality (so BOs are acting more like DTOs).

As for the point 2.
I should mention that the approach 2.1 tends to make the BOs too bloated and violate SRP. While 2.2 introduces more maintenance complexity.

I usually balance in between 2.1 and 2.2 so that I put trivial things related to the data into Business Objects and create services for a bit more complex scenarious (if there are more than 4 lines of code - make it a service).

This shifts the paradigm of Business Objects to be more Data Transfer Objects instead.

But this all makes project easier to develop, test and maintain.

笑看君怀她人 2024-08-20 05:10:09

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

对于每个班级,答案可能不同。我们最终得到了一个范围,我们可以根据责任密度来划分类别。

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

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

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

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

刚刚写完这篇文章后,我想说班级规模和组织程度之间存在相关性。 Robert C. Martin(或“Uncle Bob”)在他关于 设计原则和设计模式JDepend 是图表背后思想的实现第 26 页,并补充了 静态分析工具,例如 CheckstylePMD

The answer is the same regardless of platform or language. The key to this question is whether an object should be able to be autonomous or whether it is better for any given behavior to be spread out among objects with more focused responsibility.

For each class the answer might be different. We end up with a spectrum along which we can place classes based upon the Density of Responsibility.

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

Let's say you favor letting the class perform all the behaviours itself, or as many as you can. Starting on the left side of this graph, when you make your class more autonomous, the size of the class will grow unless you continuously refactor it to make it more generic. This leads to a template. If no refactoring is done, the temdency is for the class to become more "god-like" because if there is some behavior it needs, it has a method for that. The number of fields and methods grow and soon become both unmanageable and unavoidable. Since the class already does so much, coders would rather add to the monstrosity than try to piece it apart and cut the Gordian knot.

The right side of the graph has classes that depend on other classes to a large degree. If the dependency level is high but the individual class is small, that is a sign of a framework; each class doesn't do much and requires lots of dependent classes to accomplish some function. On the other hand, a highly-dependent class that also has a large amount of code is a sign that the class is full of Spaghetti.

The key to this question is to determine where you feel more comfortable on the graph. In any event, individual classes will end up spread out on the graph unless some organizational principle is applied, which is how you can achieve the results of Template or Framework.

Having just written that, I would say that there is a correlation between class size and degree of organization. Robert C. Martin (or "Uncle Bob") covers similar ground with package dependencies in his very thorough paper on Design Principles and Design Patterns. JDepend is an implementation of the ideas behind the graph on page 26 and complements static analysis tools such as Checkstyle and PMD.

半夏半凉 2024-08-20 05:10:09

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

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

I think it makes more sense for business objects to know how to "handle" themselves, then to have to put that burden elsewhere in the system. In your example, the most logical place to deal with how to "save" customer data would be, to me, in the Customer object.

This may be because I consider the database to be the "data container", so I'm in favor of "business objects" being the higher level that protects the data container from direct access AND enforces standard "business rules" about how that data is accessed/manipulated.

安静 2024-08-20 05:10:09

我们多年来一直使用 Rocky Lhotka 的 CSLA 框架,并且喜欢它的设计方式。在该框架中,所有功能都包含在对象中。虽然我可以看到分离逻辑的价值,但我认为我们不会很快放弃这种哲学。

We've used Rocky Lhotka's CSLA framework for years and love the way it is designed. In that framework all of the functionality is contained in the objects. While I can see the value of separting the logic out, I don't think we'll switch away from this philosophy anytime soon.

·深蓝 2024-08-20 05:10:09

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

持久性不是建模对象的行为。我发现如果业务对象对持久性一无所知,那么开发进展会更顺利。如果业务对象没有专门与底层管道相关联,那么开发新代码和对新代码进行单元测试会更快、更顺利。这是因为我可以模拟这些方面,而忘记必须通过环路才能到达数据库等。我的单元测试将执行得更快(如果您有数千个与每个构建一起运行的自动化测试,这是一个巨大的优势)并且我压力会更小,因为我不会因为数据库连接问题而导致测试失败(如果您经常离线或远程工作并且不能总是访问数据库,那就太好了,哦,顺便说一句,这些方面(数据库连接等)应该是在其他地方进行测试!)。

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

知道 Customer 有一个 Save 方法就已经知道如何保存客户对象了。您并没有通过将该逻辑嵌入到业务对象中来避免问题。相反,您使代码库耦合得更紧密,因此更难维护和测试。将保留对象的责任推给其他人。

Business objects should be about encapsulating data and associated behaviors of the business entity modeled by that object. Think of it like this: one of the major tenets of object-oriented programming is encapsulating data and associated behaviors on that data.

Persistence is not a behavior of the modeled object. I find development progresses more smoothly if business objects are persistence ignornant. Developing new code and unit testing new code happen more quickly and more smoother if the business objects are not specifically tied to the underlying plumbing. This is because I can mock those aspects and forget about having to go through hoops to get to the database, etc. My unit tests will execute more quickly (a huge plus if you have thousands of automated tests that run with each build) and I will have less stress because I won't have tests failing because of database connection issues (great if you often work offline or remotely and can't always access your database and oh, by the way, those aspects (database connectivity etc.) should be tested elsewhere!).

The other line of reasoning says, no, if I have a customer object I just want to call Customer.Save and be done with it. Why do I need to know about how to save a customer if I'm consuming the object?

Knowing that Customer has a Save method is already knowing how to save a customer object. You haven't avoided the problem by embedding that logic in your business object. Instead, you've made your code base more tightly coupled and therefore harder to maintain and test. Push off the responsibility of persisting the object to someone else.

蓝海 2024-08-20 05:10:09

业务对象,正如它们的名字一样,显然应该包含它们自己的业务逻辑,业务逻辑在服务层中的域之间的动态。

另一方面,BO是否可以是一个数据容器(DTO?)的组成和方法?意思是BO是纯功能性的?这可以避免 BO 和 DTO 之间的所有转换。

The Business objects, as they are named, should obviously coutain their own business logic, the dynamic of the business logic among the domain being in the service layer.

On the other side, could the BO be a data container (DTO?) composition and methods; meaning BO are pure functionnal? That could avoid all the conversions between BO and DTO.

是伱的 2024-08-20 05:10:09

在MVC架构中,

我们可以说模型包含业务对象吗?

In an MVC architecture,

Can we say that Model contains business objects.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文