第1章:导论。
模式能够:
利用一个经过验证可行的解决方案;
提供一套通用词汇;
约束解决方案的空间。
第2章:表现层设计考虑和不佳实践。
客户端验证:基于表单的验证、基于抽象类型的验证。
曾经在JSP中滥用过的助手类,通过助手类在页面和业务逻辑之间传递数据,有点类似于如今Struts中的Action作为传值模型时的情况。
表现层不佳实践:
多个视图中都包含控制代码;
表现层数据结构暴露给业务层或者业务领域对象,比如:暴露HTTPServletRequest;
重复提交表单;
敏感资源暴露给客户端直接访问,有个原则,敏感的东西不能放在WEB-INF之外;
胖控制器;
……
怎么区分后台视图层和前台页面层?或者说,怎么划分哪些事情JSP或者模板做,哪些事情JavaScript做?首先,根据模型驱动的原则,通常送到JSP或者模板上的都是通用模型的对象或者对象集,JSP或者模板根据需要选择展示出来,但是后续可抽取为不需和服务端交互状态下响应用户的行为,应当划分为JavaScript的工作。
第3章:业务层设计考虑和不佳实践:
session bean:根据EJB规范,每个session bean专门服务于一个客户端或者用户,生命时间等于客户端会话时间;在服务器崩溃后无法存活、无法持久化、会超时、可以涉及事务;支持构造有状态或无状态的对话模型。
不过现在的容器会话大多可以持久化了,会话复制和会话持久化应当是会话管理中重要的两个分支,通常情况下会话不需考虑完整的事务性,保证线程独立性即可。
至于无状态的session bean,可以被池化,以高效利用(EJB容器管理)。
entity bean:实体bean是否应该包含业务逻辑?按照下面三个原则去判定,还是比较清晰的:
这样的业务逻辑是否会引入实体之间的关系?比如处理UserInfo的时候,是否引入了AccountInfo,这样应当考虑根据模型驱动的原则,放置到专门的User或者Account相关的业务无状态bean中去;
是否要负责管理用户交互的工作流?
是否会担负起本该属于其他业务组件的责任?
有一个“是”,就说明不该包含这段业务逻辑。
尤其提一句,如果使用远程实体bean,就更应该减少实体bean之间的依赖关系,以提高性能和可用性。
业务层和集成层不佳实践:
对象模型或关系模型或每个用例直接映射成实体bean:导致粒度过细,EJB就给网络传输带来太多的负担;
通过getter、setter暴露EJB所有属性:这也是不好的,提供少量和可控的方法调用,减少远程方法调用的开销;
客户端中包括服务寻址代码:寻址这件事情应当从单纯的客户端抽离出来,把不同的寻址策略和复杂度封装起来,真正做到透明传输(扩展到without EJB的系统中也一样,集群环境中也一样,把寻址的行为隐藏于业务逻辑之下)。
EJB用户长时间持续的事务:会锁住其他EJB需要的资源;
……
第4章:J2EE重构:
对业务层隐藏表现细节:对用户请求的处理和通信协议相关的数据不应当被业务层获取,最简单的例子就是HttpServletRequest对象。
用session bean包装entity bean:现在这里说的问题一般不会出现,一般也不会有人直接把Action对象扔给后面的业务逻辑去处理,原文说的解决办法是引入业务代表,涉及到此的还有两条:减少entity bean之间的通信;将业务逻辑移至session bean。
分离数据访问代码:DAO。
按层重构系统架构(这里也正好归纳一下现在J2EE系统中常涉及到的Action、Service和EJB中的几种bean的内在联系),例如:
客户端层:浏览器
表现层:JSP、模板、业务代表
业务层:entity bean(Action)、session bean(各种粒度的Service)
集成层:DAO
资源层:DB
……