J2EE表现层模式--前端控制器
问题:
你想给表现层的请求处理安排一个集中访问点。
系统需要一个几种的访问点来处理请求。如果没有几种访问点,那么多个请求之间共用控制代码就会在许多文件中重复的出现<比如视图文件>中重复出现。如果控制代码和视图创建代码混在一起,整个应用系统的模块化程度和内聚性都要下降。另外,如果控制代码在多处散放,也不便于代码维护,只要代码有一处改动,就需要改动多个文件。
约束:
--你想要避免重复控制逻辑
--你想要对多个请求采取共同的处理逻辑。
--你想把系统处理代码和视图分隔开(不要在视图中写控制代码)
--你想要把系统的访问点集中在一点
解决方案:
使用给一个前端控制器,作为最初的接触点,用来处理所有相关的请求。前端控制器几种了控制逻辑,避免了逻辑的重复,完成了主要的请求处理操作。
前端控制器为处理请求提供了一个集中的入口点。因此能够集中控制逻辑,因此就减少了直接置入视图的代码量。
这个模式和拦截过滤器相似,因为两者都提取、合并了表现层的一些共同控制逻辑。一个主要区别在于:
拦截过滤器--提供了一组松耦合的、结成一条链的处理器,以及一些特别适合进行预处理和后处理的强大策略。
前端控制器--集中控制、减少视图的业务、处理逻辑,就能够提高多个请求之间代码的重用度,减少代码重复。除非视图中的代码微乎其微,否则使用前端控制器就要优于在多个视图中置于代码,因为后者是一种“复制-粘贴”的重用,这样的代码很脆弱。
另外,如果在多个视图置入代码,还会使团队中的每个开发者用不同的方法完成同样的任务--而这种处理本来是完全一致的,应该统一、规范的方式集中完成。比如,如果由每个开发者在页面中加入<tag:checkLogin/>标记,实现对特定页面的访问逻辑,那么就很难保证一直的效果,因为可能就有开发者忘了做这件事情。
前端控制器通常会使用应用控制器,后者负责操作和视图管理。
操作管理--也就是定位特定的操作action,并把控制权路由到该操作上、由他处理逻辑请求。
视图管理--则是找到合适的视图,并分配到该视图上。虽然这个任务也可以放进前端控制器完成,但是把它独立出来,成为应用控制器的一部分功能,能够增进模块化、可维护性和可重用性。
虽然处理相关请求的工作集中了,但是这并不意味着对系统中处理器数量做了任何的限制。一个最常见的做法是由一个前端控制器处理所有的请求,但是应用系统当然也可以有多个控制器,每个控制器对应于一类服务。
对于前面只使用一个控制器的通常的情况,服务器管理任务比较少,因为WEB服务器只需注册一个组件。这也意味着增加一种服务并不需要在web服务器上注册改服务。这减少了管理负担,更便于热部署,可以结合struts1.2来好好考虑。
而对于使用多控制器的情形,每个控制器都必须在web服务器上注册。增加一种服务也需要在web服务器上注册。
设计手记:处理请求
处理请求需要两种操作:请求处理和视图处理。在请求处理过程中,表现层中又必须进行几种操作:
--协议处理和上下文转换
--导航和路由
--核心处理
--分派
协议处理--是指处理与特定协议相关的请求,上下文转换是指吧与特定协议相关的状态转换成更具有通用的形式。一个例子是,从HttpServletRequest实例中获取参数,在复制到一个myRequest对象中,从而能够在servlet环境之外独立应用。
导航路由--是指一个特定的请求的路由,比如用哪些对象进行请求的核心处理,用哪个视图显示结果。
核心处理--对请求的实际处理
分派--是指把控制权从一个系统的一部分转交给另一个部分,比如从请求处理机制转交给视图处理组件。
策略:
--servlet前端策略
--JSP前端策略
--命令加控制器策略
--物理资源映射策略
--逻辑资源映射策略
--多路资源映射策略
--“控制器中的分配器”策略
效果:
--集中控制
--提高系统的可维护性
--增进了重用
--增进了开发团队中职责之间的区分