a. 问题
MVC给出了一个整个应用的松散的耦合架构。现在来看一下这样一个经常发生的情况。在某一个应用中,用户看到的视图和他所做的操作密切相关。这是一些具有高度交互性的页面,而这些页面之间含有高度的依赖性。在没有任何模式的时候,这个应用只是一个许多独立的页面的集合,维护和扩展变得异常困难。
§ 当一个页面移动后,其他含有这个页面链接的文件,都必须修改。
§ 当有一系列页面需要口令保护时,许多配置文件需要修改,或者页面需要包含新的标记。
§ 当一个页面需要一个新的表示层时,页面中的标记要被重新安排。
当这个系统变得复杂时,这些问题将变得更糟。如果用MVC来解决的话,就变成一个如何管理控制器和视图之间交互的问题。
b. 建议的解决方法
前台控制模式可以解决这个问题。这个模式中,所有的请求都被传送到一个对象中。这个主要的对象将处理所有的请求,决定以后显示那一个视图,以及实现必要的安全需求。对于把视图显示以及其他功能实现集中到一个主要的对象中,将使修改变得很容易,对应用的修改,可以在所有视图中反映出来。
c. 要点
§ 这个模式对于需要在多个含有动态数据的页面之间进行复杂导航的系统来说,是很有效的。
§ 这个模式对于要在所有页面中都包含模板,转换等的应用来说,也是很有效的。
§ 由于视图的选择集中在前端控制器上,因此,视图的导航变得更加容易理解和便于配置。
§ 视图重用和变更会更加容易。
§ 视图之间的复杂交互,使得控制器变得复杂。从而,当应用发展的时候,控制器将变得难以维护。不过,大部分情况下可以用XML映射来解决。
§ 实现应用要求的安全性检验变得很简单。
§ 这个模式不适合小型的,只显示静态内容的应用。
d. 样例
§ RequestMappings.xml 文件映射了传入的请求,处理器以及下一个页面。
useRequestHandler="true"
requiresSecurityCheck="true" nextScreen="screen2.jsp">
com.blah1.blah2.blah3.request1Handler
以上这个文件是控制器的指定配置,控制器的代码如下:
§ FrontControllerImpl.java 利用上面的XML实现了控制器
// all required imports
// exceptions to be caught appropriately wherever applicable
public class FrontControllerImpl extends HttpServlet {
// all required declarations, definitions
private HashMap requestMappings;
public void init() {
// load the mappings from XML file into the hashmap
}
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
doGet(request, response);
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
String currentPage= request.getPathInfo();
// get all mapping info for "currentPage" from the hashmap
// if "securityCheckRequired = true", do the security check
// if "useRequestHandler = true", pass on the incoming request to the specified handler
// forward the results to the given "nextScreen"
}
}
用这种方法实现的控制器将很容易维护,当应用有新的变动的时候,只要修改XML文件就能解决了。前台控制模式将使在视图和控制器之前有复杂交互的J2EE应用变得简单。