[英]Looking for the best way to make a web framework more OO on the server side
Web框架似乎总是远离良好的OO代码(在将代码和数据分组到一个对象中,从向该对象发送消息的角度进行思考等)。
主要问题似乎是bean模式的存在。 您可以使用bean模式(由于人们似乎不了解它们之间的区别,如今通常称为POJO)与数据库,Web服务和大多数其他事物进行交互。
因此,没有您会陷入没有代码的setter和getter之类的麻烦中,因此您倾向于添加一堆非常好的静态函数来操纵这些事情。 OO代码的几乎所有优点都消失了。
我看到了我正在考虑的三个解决方案,但想听听它们是否存在任何严重的缺点。
1)使用POJO模式而不是bean模式。 这意味着从POJO中消除设置者和获取者(这样就可以保证封装/数据安全性),而是添加业务逻辑方法。 这似乎是最合理的-实际上,我认为这就是为什么休眠之类的库从要求Bean转向允许POJO的原因,但是每个人似乎仍然使用Bean模式。
2)使用业务逻辑类扩展Bean,该业务逻辑类使用Bean的字段作为存储。 这似乎很容易出错,但很容易放入现有的代码库中进行迁移...
3)用业务逻辑对象包装Bean模式对象。 通常,我认为如果#1确实有问题,这可能是必要的。
我最想知道的是为什么我从未见过使用过#1。 我真的很想听听任何人使用Pojo模式(具有业务逻辑并且没有设置器和获取器)来休眠对象,并且对它有问题(或使其工作得很好)...
我将我的评论更改为答案。 我基本上不同意你的开业前提
Web框架似乎总是偏离良好的OO代码。
Java EE或Spring / JPA模型中的任何内容都没有“偏离良好的OO代码”。 JPA提供程序(例如休眠)允许POJO的事实并不意味着您不能使用丰富的域模型,该模型定义了bean中的业务逻辑。 对于Java Web应用程序,我已经看到它同时完成了两种工作-富域模型或带有服务层中业务逻辑的贫乏域模型,非OO或糟糕的设计都是不必要的。
我认为您可能要说的是,很多应用程序的设计和/或面向对象设计不正确。 我会同意。 但这与框架无关。
因此,您提出的解决方案基本上都说“使用良好的OO原则正确设计您的应用程序”。 选项1是最简单的。
我对您在这里究竟在争论什么感到困惑,因为您都说人们倾向于将bean称为“ POJO”,然后您建议不要使用bean,而应使用“ POJO”。 但是要回应这一点:
因此,没有您会陷入没有代码的setter和getter之类的麻烦中,因此您倾向于添加一堆非常好的静态函数来操纵这些事情。 OO代码的几乎所有优点都消失了。
我不同意这一点-如果您正在编写用于操作对象的静态函数,则您的设计有问题。
通常,常见/“最佳”实践是将业务逻辑包装在类的“服务层”中,该类知道如何处理数据(以bean,POJO,域对象表示,无论您想调用它们如何表示)作为响应。遵守应用程序规则。
没有人阻止您使用子类和继承以及所有这些来对您的“服务层”进行面向对象设计。
通常,您不会看到有人在构建一个应用程序,其中保存数据的Employee
类还包含对Employee
执行操作的方法和逻辑,因为人们倾向于将数据(由Employee
类表示)与逻辑分离。 从实践上讲,一旦您开始在Employee
类中对员工实例进行操作的方法,那么就需要让Employee
类能够调用存储层本身,现在需要使用Hibernate来表示该类。查询的结果( Employee
类)也引用了Hibernate代码来加载自身,这变得非常混乱。
我认为您看到的“问题”仅是您对这些类型的应用程序中常见的设计思想的分歧。 大多数人想将数据的表示方式与封装应用程序逻辑的代码分开。
有充分的理由将(大多数)业务逻辑保留在数据对象之外,但最佳设计将在其中包含某些部分。 要做到这一点并不容易,尤其是在蓝领团队中,我猜这是所有Java开发团队中的95%。
我喜欢在我的数据对象中放入一些简单,独立,可广泛使用的逻辑。 与数据固有耦合的代码,而不考虑任何特定的业务请求。 例如转换,验证等。
至于吸气剂和吸气剂,我不惜一切代价避免它们。 您可以使用公共最终字段,也可以使用简单的公共字段。 getter + setter组合为您提供与公共字段一样多的封装:零。
至于ORM解决方案,我严格使用Hibernate作为SQL的便利,而不是用作持久状态管理器。 映射的类仅作为XML映射的替代品。 它们甚至从未在读取操作中实例化。 对于插入,我分别保存每个对象,该对象与单个数据库行一对一映射,而没有传递持久性。 基本上,这意味着我的Hibernate模型对象只是一种查看数据库行的Java方法(加上方便的联接列规范-如果没有那些多余的联接条件,HQL看起来会更好)。
根据最佳实践, 业务逻辑应与表示逻辑分开 。 大多数Web框架都围绕数据表示提供了不错的功能。 涉及数据检索/处理的任何业务逻辑都应编写在Business Layer
,这是presentation layer
和data layer
之间的附加data layer
。 POJO
对象充当Business Layer
和Presentation Layer
之间的数据载体。 POJO
是非常好的候选对象,因为它们是非常轻的对象,具有作为访问器方法的属性。
休息由您决定。 如果您想在其中包含业务逻辑的复杂bean对象一起使用,我认为没有任何Web框架会阻止您这样做。
希望这可以帮助。
“我最想知道的是为什么我从未见过使用过的#1。” 关注点分离,单一职责原则(可能是所有职责中的大多数原则),可测试性等。“万物联结万物”的模型很方便,但客观上很糟糕。 (这并不是说方便的API表面是不好的,但是应该在结构良好,可测试的代码上构建它们,而不是代替它。)
例如,当您在业务逻辑层上添加一个“哑” DTO层时(其中每个视图都映射到一个包含创建视图所需的所有内容的Bean),您将摆脱诸如必须保持会话打开才能获取关联对象之类的问题。属性,或使ORM争先恐后地获取它们。 (前者还意味着存在N + 1选择问题,这会增加数据库往返次数。)
如果每个请求都由专用服务层上的单个方法调用来满足,则也使跟踪事务范围变得更加容易。 然后,此调用是对数据的单个逻辑操作,这使得设置事务处理变得微不足道。
最后但并非最不重要的一点是,这种方法导致小型类易于理解和自行更改。 例如,如果您需要更改用于计算平均成绩的算法, GradePointAverageCalculator
开始并从那里导航,而不是代码范围,您需要查看的是“ Student.java
,行1340至1486,然后1502至1689,…… “
也许您可以研究其他Knockout(JavaScript框架)所使用的Model-View-View Model设计模式。 这里将视图模型作为模型和视图之间的一层引入,从而使将视图与模型分离成为可能。
在此处了解更多信息: http : //knockoutjs.com/documentation/observables.html ..以及此处http://en.wikipedia.org/wiki/Model_View_ViewModel
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.