Java EE/J2EE面向对象编程之道
http://www.jdon.com/artichect/javaee.html
请问:像Tapestry 这样的框架是否算是以上所说的旁门左道那?这种框架几乎所有的逻辑都是与页面有关的。
不过Tapestry性能上好像有些微词,TheServerside就是用Tapestry+JDO做的,很慢,Tapestry作者认为是后台JDO的问题,反正TSS打开页面很慢。
在Hibernate当中肯定要设one to many关联查询,
但是如果我有某个页面只是想得到A的当中的name和id就可以了,但每次通过hibernate查询都会相应的把B和C的集合都包含进来(数据少的话那倒是不要紧,但如果多的话那就要命了)。
请问如果遇到这种情况该怎么设置呢?
另外,如果根据Evans DDD,持久层提供完整的A对象,这时需要将B和C集合包括进来,出现这种情况有两种方式处理:1.检查模型A B C建模正确与否?按照高聚合 低关联设计原则,A是否真的包含多个B?B又包含多个C?
2.使用批量查询等lazy方式来对集合进行查询,就象Hibernate3这样处理一样
Banq表误导俺们呀,谁说Open session in view是在表现层“一直”打开session的?对于缺省的配置,OpenSessionInViewFilter会在一个请求(request)的开始的时候,打开一个session。Spring绝的地方在于,该请求之后的所有用Spring方式打开的session都是这个session,因为这个session是与Thread绑定的。当请求结束,OpenSessionInViewFilter会关闭这个session的。如果将singleSession属性设置为false,那么OpenSessionInViewFilter不会打开session,请求处理过程中所使用的session就是原来的那个(就像没有用OpenSessionInViewFilter)。但是,这个session会延迟关闭。
看看spring的代码就知道了。
使用OpenSessionInViewFilter似乎是破坏了分层,但是却大大简化了开发,比使用Hibernate的强制即时加载和直接用JDBC破坏延迟加载的方式不知要简单多少。而且,这种对分层的“破坏”,是隐藏在框架中的。开发者只需要配置一个OpenSessionInViewFilter即可,代码中看不到破坏分层的坏味道。
从性能上来说,对于单个请求而言session的关闭被延迟了,的确会降低性能。但是,这种性能的降低是和延迟加载所提高的性能是可以抵消的。如果通过性能测试,发现OpenSessionInViewFilter“的确”降低了性能,那么可以通过URL-Pattern的配置绕过不需要OpenSessionInViewFilter的请求。例如,带有query或list的URL使用OpenSessionInViewFilter,而带有save或update的则不使用OpenSessionInViewFilter。
我的理解是这个Thread是每个客户端对应一个thread, Web是一个多线程环境,你能说这个session不是和客户端相关的?从设计高度来说:session必然由客户端决定的,我没有研究Spring这部分代码,但是我想它绝也不会绝到跳出设计常理。
>使用OpenSessionInViewFilter似乎是破坏了分层,但是却大大简化了开发
是的,如果我们使用Delphi/VB等两层系统,还更加简化的,我一直强调,简化的前提不能牺牲分层原则。
>从性能上来说,对于单个请求而言session的关闭被延迟了,的确会降低性能
更坏的性能是Hibernate自己都承认:当出现Exception出错抛错的时候,导致大量资源可能无法关闭,这是最危险的。
正因为有这些陷阱在,所以才出现不少Spring+Hibernate系统缓慢存在,一个好的架构不应该在基础功能:性能上留有陷阱,即使它的设计超前时代几十年...
总之,在找不到两全其美的情况下,我目前是用JDBC来实现,这也符合Evans DDD的仓储原理。
http://www.jdon.com/jdonframework/rails.html
>当出现Exception出错抛错的时候,导致大量资源可能无法关闭,这是最危险的
这个我之前没有表达清楚,Open session in view模式在复杂系统中就不是在web.xml设置一句filter那么简单了,真的会导致系统性能下降缓慢。
因为后台Hibernate的session被前面表现层hold后,这个环节因为跨表现层和复杂的业务层以及持久层。
万一(注意,这是随时可能发生的,一个用户等不及浏览器打开页面就关闭等等),三个层中任何一个环节任何一个点出错,就会抛Exception,那么这个跨环节的过程就会崩溃。
关键问题是:崩溃后,我们如何做善后处理?如何将这个过程涉及的多个环节中打开的一些资源(不一定是数据库连接,有可能使用缓存资源保存了很多垃圾数据)进行清除。
如果不进行Exception捕获善后处理,那么就有可能引起内存泄漏,就象一个房间里举行过party,无论是否成功完成或中途结束,肯定要进行现场清扫,垃圾回收。
如果进行Exception捕获,又何其的难,跨多个层的执行循序我如何能进行逆转判断,然后逐个关闭一些资源?当然除非你是明显的过程化编程。
因此,这是一个很棘手的问题,尤其是系统复杂,也就是业务层庞大时。
这种Open session in view模式我个人一直是持反对态度,这是典型使用模式来弥补基础功能的缺失,是反模式的。见以前这个帖子:
http://www.jdon.com/jive/thread.jsp?forum=62&thread=22251&message=14293011
当然,喜欢使用Open session in view模式尽管使用,以上只是我个人想法。
In a web-based application, a servlet filter can be used to close the Session only at the very end of a user request, once the rendering of the view is complete (the Open Session in View pattern). Of course, this places heavy demands on the correctness of the exception handling of your application infrastructure. It is vitally important that the Session is closed and the transaction ended before returning to the user, even when an exception occurs during rendering of the view. See the Hibernate Wiki for examples of this "Open Session in View" pattern.
大意翻译:在基于Web应用中,我们可以为每个用户请求一直打开session,直至这个请求输出结果页面结束。这就会严格要求你有正确的exception捕获上(这就是难度,当要求你小心行路时,说明脚下有陷阱了,这就是性能陷阱)。下面就非常注意:即使在一个请求结束后输出页面时出错,也必须在结果返回给用户客户端之前,关闭Session和事务,(注意,这里是指session和事务,这些Spring可能能够帮助你完成,但是如果是你自己打开的一些资源占用,如打开文件资源准备写等)。
Arjen Poutsma说:
计算科学告诉我们有三种方式来表达数据:
1. Object graphs (i.e. Java or C#) 对象
2. Relational data (RBMS) 关系数据库
3. Hierarchal data (XML or HTML) 树形层次数据
Data is generally stored in relational databases, and converted to Java or .NET objects using some kind of ORM tool. Next, we use the objects to invoke business logic, and finally, we display them on an HTML page. I find this very amusing, it makes me feel we are doing something wrong here.
译文大意:(现在J2EE OO系统大部分是这样做的,如本文提到的:)数据通常保存在关系数据库中,然后通过一些ORM工具转换为Java或.NET对象,我们可以使用这些对象进行业务逻辑处理,最后将他们显示在HTML页面上,这给我的感觉好像有些问题。
Recently, though the influence of books like Domain Driven Design, it has become fashionable to think that a rich Domain Model is one of the most important things there is.
最近,因为Domain Driven Design书籍的流行,一个丰富的Domain Model概念被提出来了。
Well, that might be the case for you as an OO developer, but for the Enterprise the database is much more important.
不错,也许这样你就成为了一个OO开发者,但是企业数据库也许更重要!
It is not without reason that a large number of databases outlive the applications built around them.很显然很多数据库比他们的应用系统活得更长。
And for the user of your Web application the most important part is the HTML UI he or she is looking at.
对于Web应用系统,最重要的是人们看到的Html界面(这也是某些坚持AJAX比DDD更重要的原因)
Finally, in this SOA day and age, the OO business logic is probably not the only business logic that is there. Your application is part of a team of services, the business logic on the mainframe is just as important!
最后,在SOA年代,OO业务逻辑大概不只是就是某个地方一点点业务逻辑,你的应用是一系列services服务的一部分,大型主机中业务逻辑也重要。
Now, I’m not saying that a rich domain model is not important. I’m just saying that ― as with any solution ― it is not a silver bullet. Use it when it gives an advantage, but don’t swear by it. In the grand scheme of things, your precious OO model is not as important as you think it is.
当然我并不是说胖Domain Model(rich domain model )不重要,我想表达的是:正如其他解决方案:它不是银弹,使用其优点。
这一点引发了更多的关于数据库和对象的争论,见TSS帖子:
http://www.theserverside.com/news/thread.tss?thread_id=42602
http://today.java.net/pub/a/today/2006/07/13/lazy-loading-is-easy.html
当然,文中提到了RDM(Rich Domain Model)和贫血模型、失血模型(anemic model )比较,注意这里RDM不是指在模型对象里带有数据库操作save;get等行为的RDM,Evans DDD是坚决反对将持久层行为耦合到领域层的,这里的RDM不是传统意义的RDM,是Evans DDD中的RDM