zoukankan      html  css  js  c++  java
  • Front Controller(前端控制器)

    http://msdn.microsoft.com/zh-cn/library/ms978723.aspx#EFAA
    背景

    您已经决定使用Model-View-Controller (MVC) 模式将动态 Web 应用程序的用户界面逻辑与业务逻辑分隔开来。您已经考察了Page Controller模式,但您的页面控制器类具有复杂的逻辑,并且是较深的继承层次结构的一部分,或者,您的应用程序是基于可配置的规则来动态确定页面导航的。

    问题

    如何为非常复杂的 Web 应用程序构建最佳的控制器结构,以便在避免代码重复的同时实现重用性和灵活性?

    影响因素

    下面是适用于 Front Controller 模式的、由 Model-View-Controller 带来的各种具体的影响因素:

    • · 如果在系统的不同视图内复制公共逻辑,则需要集中此逻辑才能减少代码重复量。删除重复的代码是改进系统的总体可维护性的关键。
    • · 数据检索最好也集中在一个位置进行处理。一个好的示例是,让一系列视图使用数据库中的相同数据。与让每个视图检索数据并重复数据库访问代码相比,在一个位置实现对此数据的检索是更好的做法。
    • · 如 MVC 中所述,测试用户界面代码往往是耗时而乏味的。通过区分单各自的角色,可以提高总体可测试性。这不仅适用于模型代码(在 MVC 中已说明),而且适用于控制器代码。

    以下影响因素可能使您决定使用 Front Controller,而不是 Page Controller

    • · Page Controller 的一般实现方法涉及为各个页面所共享的行为创建一个基类。但是,随着时间的推移,由于要增加非所有页面公用的代码,这些基类就会不断增大。若需要定期重构此基类以确保其只包括公共行为,则需要制定规则。例如,您不希望由页面检查请求并决定(基于请求参数)是否将控制权转移给另一个页面,因为这种类型的决定对于特定功能来说更具体,而不是所有页面共有的。
    • · 为了避免在基类中添加过多的条件逻辑,您会创建更深的继承层次结构以删除条件逻辑。例如,在具有三个功能区域的应用程序中,只使用一个包含应用程序公共功能的基类可能是很有用的。每个功能区域可能还有另一个类,该类继承总体应用程序的基类。乍一看,这种类型的结构是简单的,但它通常会导致非常脆弱的设计和实现,并给代码带来问题。
    • · Page Controller 解决方案描述了每个逻辑页面使用一个对象。当需要跨多个页面对处理过程进行控制或协调时,此解决方案将不可行。例如,假定在 Web 应用程序中具有复杂的可配置导航(以 XML 格式存储)。当收到请求时,应用程序必须根据其当前状态查找下一步要前进到哪个位置。
    • · 由于Page Controller 是通过每个逻辑页面使用一个对象来实现的,因此,很难在 Web 应用程序的所有页面中一致地应用特定操作。例如,安全性最好以协调方式实现。让每个视图或页面控制器对象分别处理安全性是有问题的,因为它可以被不一致地应用,并导致安全问题。此问题的其他解决方案还将在Intercepting Filter 中进行讨论。
    • · 对于 Web 应用程序来说,URL 与特定控制器对象的关联可以是强制性的。例如,假定您的站点具有类似向导的界面用于收集信息。此向导包括许多必备页面和许多基于用户输入的可选页面。在使用 Page Controller 实现时,必须使用基类中的条件逻辑来实现可选页面,才能选择下一页面。
    解决方案

    Front Controller 通过让单个控制器负责传输所有请求,从而解决了在 Page Controller 中存在的分散化问题。控制器本身通常分为以下两部分实现:处理程序命令层次结构(见图 1)。

    图 1:Front Controller 结构

    处理程序具有以下两项职责:

    • 检索参数。处理程序接收来自 Web 服务器的 HTTP Post 或 Get 请求,并从请求中检索相关参数。

    • 选择命令。处理程序首先使用请求中的参数选择正确的命令,然后将控制权转移给该命令以便执行处理。

    图 2 显示这两项职责。

    图 2:Front Controller 的典型方案

    命令本身也是控制器的一部分。命令代表具体的操作,这在 Command 模式 [Gamma95] 中有相应的介绍。通过将命令表示为单独的对象,控制器可以按一般方式与所有命令交互,这与调用公共命令类上的特定方法相反。在命令对象完成操作之后,将由命令选择使用哪个视图来显示页面。

    示例

    请参阅在 ASP.NET 中使用 HTTPHandler 实现 Front Controller

    Front Controller 模式具有下列优缺点:

    优点

    • 集中化控制。 Front Controller 用于协调向 Web 应用程序发出的所有请求。此解决方案描述了使用单一控制器,而不是 Page Controller 中所用的分布式模型。此单一控制器处于很好的位置来实施全应用程序范围的策略,如安全性和使用情况跟踪。(记得国内有个PHP开源开发框架叫ThinkPHP也有这个特点。)

    • 线程安全。由于每个请求都涉及创建新的命令对象,因此命令对象本身不需要是线程安全的。这意味着,命令类中避免了线程安全问题。但是,这并不意味着您可以完全避免线程问题,因为命令所作用的代码(即模型代码)仍然必须是线程安全的 [Fowler03]。

    • 可配置性。只需要在 Web 服务器中配置一个前端控制器;处理程序执行其余的调度。这简化了 Web 服务器的配置。一些 Web 服务器是很难配置的。使用动态命令可以添加新的命令,而无需进行任何更改 [Fowler03]。

    缺点

    • 性能考虑事项。 Front Controller 是用来处理对 Web 应用程序的所有请求的单个控制器。在这两部分中,应该仔细检查处理程序中是否有性能问题,因为处理程序将确定负责执行请求的命令的类型。如果处理程序必须执行数据库查询或 XML 文档查询才能作出决定,则可能导致性能非常缓慢。

    • 增加了复杂性。 Front Controller Page Controller 更复杂。它通常涉及将内置控制器替换为自定义的 Front Controller。实现此解决方案会增加维护成本和新手的学习难度。

    测试考虑事项

    从视图中删除业务逻辑简化了视图的测试难度,因为此后可以在独立于控制器的情况下测试视图。如 Page Controller 模式中所述,测试控制器可能受到以下情况的阻碍:控制器包含了使其依赖于 HTTP 运行时环境的代码。通过使用两阶段的 Web 处理程序(如 Martin Fowler 所著的 Patterns for Enterprise Application Architecture [Fowler03] 和 Page Controller 模式中所述),可以解决此依赖问题。控制器被分为两部分:Web 处理程序和调度程序。Web 处理程序从 Web 请求中检索数据,并以调度程序不依赖于 Web 服务器框架的方式(例如,在一个常规集合对象中),将其传递给调度程序。这样,就可以在没有 Web 服务器框架的情况下测试调度程序。

    相关模式

    有关详细信息,请参阅下列相关模式:

    • Intercepting Filter。此模式描述了在 Web 应用程序内实现重复功能的另一种方式。Intercepting Filter 的工作原理是,先通过可配置的筛选器链传递每个请求,然后将控制权传递给控制器。筛选器往往会处理较低级别的功能(如解码、授权、验证和会话管理),而 Front Controller Page Controller 则处理应用程序级别的功能。筛选器的另一个方面是它们通常是无状态的。例如,在开始对用户授权时,Web 服务器必须验证会话。如果用户已通过身份验证,则过程继续进行。如果没有,则将用户重定向到其他位置。Intercepting Filter 的一个优点是,在大多数实现中,不必修改页面本身就能添加其他功能。

    • Page Controller。此模式是 Front Controller 的更简单替代方案。在 Page Controller 模式中,每个页面各有一个控制器对象,这与所有请求使用一个对象的方案相反。对于大多数应用程序来说,Page Controller 是更合适的起点。仅当需要 Front Controller 时才应该使用它。

  • 相关阅读:
    Data Structure and Algorithm
    Data Structure and Algorithm
    Data Structure and Algorithm
    Data Structure and Algorithm
    Data Structure and Algorithm
    Data Structure and Algorithm
    Data Structure and Algorithm
    Data Structure and Algorithm
    Data Structure and Algorithm
    Data Structure and Algorithm
  • 原文地址:https://www.cnblogs.com/luqingfei/p/2971142.html
Copyright © 2011-2022 走看看