日期:2014-05-19  浏览次数:20681 次

J2EE表现层模式--前端控制器
问题:

你想给表现层的请求处理安排一个集中访问点。

系统需要一个几种的访问点来处理请求。如果没有几种访问点,那么多个请求之间共用控制代码就会在许多文件中重复的出现<比如视图文件>中重复出现。如果控制代码和视图创建代码混在一起,整个应用系统的模块化程度和内聚性都要下降。另外,如果控制代码在多处散放,也不便于代码维护,只要代码有一处改动,就需要改动多个文件。

约束:

--你想要避免重复控制逻辑

--你想要对多个请求采取共同的处理逻辑。

--你想把系统处理代码和视图分隔开(不要在视图中写控制代码)

--你想要把系统的访问点集中在一点

解决方案:

   使用给一个前端控制器,作为最初的接触点,用来处理所有相关的请求。前端控制器几种了控制逻辑,避免了逻辑的重复,完成了主要的请求处理操作。

   前端控制器为处理请求提供了一个集中的入口点。因此能够集中控制逻辑,因此就减少了直接置入视图的代码量。

    这个模式和拦截过滤器相似,因为两者都提取、合并了表现层的一些共同控制逻辑。一个主要区别在于:

拦截过滤器--提供了一组松耦合的、结成一条链的处理器,以及一些特别适合进行预处理和后处理的强大策略。

前端控制器--集中控制、减少视图的业务、处理逻辑,就能够提高多个请求之间代码的重用度,减少代码重复。除非视图中的代码微乎其微,否则使用前端控制器就要优于在多个视图中置于代码,因为后者是一种“复制-粘贴”的重用,这样的代码很脆弱。

   另外,如果在多个视图置入代码,还会使团队中的每个开发者用不同的方法完成同样的任务--而这种处理本来是完全一致的,应该统一、规范的方式集中完成。比如,如果由每个开发者在页面中加入<tag:checkLogin/>标记,实现对特定页面的访问逻辑,那么就很难保证一直的效果,因为可能就有开发者忘了做这件事情。

   前端控制器通常会使用应用控制器,后者负责操作和视图管理。

  操作管理--也就是定位特定的操作action,并把控制权路由到该操作上、由他处理逻辑请求。

  视图管理--则是找到合适的视图,并分配到该视图上。虽然这个任务也可以放进前端控制器完成,但是把它独立出来,成为应用控制器的一部分功能,能够增进模块化、可维护性和可重用性。

  虽然处理相关请求的工作集中了,但是这并不意味着对系统中处理器数量做了任何的限制。一个最常见的做法是由一个前端控制器处理所有的请求,但是应用系统当然也可以有多个控制器,每个控制器对应于一类服务。

  对于前面只使用一个控制器的通常的情况,服务器管理任务比较少,因为WEB服务器只需注册一个组件。这也意味着增加一种服务并不需要在web服务器上注册改服务。这减少了管理负担,更便于热部署,可以结合struts1.2来好好考虑。

  而对于使用多控制器的情形,每个控制器都必须在web服务器上注册。增加一种服务也需要在web服务器上注册。

设计手记:处理请求

处理请求需要两种操作:请求处理和视图处理。在请求处理过程中,表现层中又必须进行几种操作:

--协议处理和上下文转换

--导航和路由

--核心处理

--分派

协议处理--是指处理与特定协议相关的请求,上下文转换是指吧与特定协议相关的状态转换成更具有通用的形式。一个例子是,从HttpServletRequest实例中获取参数,在复制到一个myRequest对象中,从而能够在servlet环境之外独立应用。

导航路由--是指一个特定的请求的路由,比如用哪些对象进行请求的核心处理,用哪个视图显示结果。

核心处理--对请求的实际处理

分派--是指把控制权从一个系统的一部分转交给另一个部分,比如从请求处理机制转交给视图处理组件。

策略:

--servlet前端策略

--JSP前端策略

--命令加控制器策略

--物理资源映射策略

--逻辑资源映射策略

--多路资源映射策略

--“控制器中的分配器”策略

效果:

--集中控制

--提高系统的可维护性

--增进了重用

--增进了开发团队中职责之间的区分