Tomcat源码阅读系列(八)设计模式

本文是Tomcat源码阅读系列的第八篇文章,本系列前七篇文章如下:
Tomcat源码阅读系列(一)使用IntelliJ IDEA运行Tomcat6源码
Tomcat源码阅读系列(二)Tomcat总体架构
Tomcat源码阅读系列(三)启动和关闭过程
Tomcat源码阅读系列(四)Connector连接器
Tomcat源码阅读系列(五)Catalina容器
Tomcat源码阅读系列(六)类加载器
Tomcat源码阅读系列(七)Session管理机制
本文主要介绍Tomcat中用到的主要设计模式。

1 门面模式(外观模式)

定义
外观模式提供了一个统一的接口,用来访问子系统中的一群接口。外观模式定义了一个高层接口,让子系统更容易使用。外观模式又称为门面模式,它是一种对象结构型模式。外观模式封装了子系统的具体实现,提供统一的外观类给外部系统,这样当子系统内部实现发生变化的时候,不会影响到外部系统。
Tomcat中的应用
在Tomcat中对于Request,Response,StandardSession,ApplicationContext,StandardWrapper都采用了外观模式,它的类图如下:
门面模式
通过上图,我们可以看到RequestFacade包装了Request,它们都实现了HttpServletRequest,当传递Request对象给应用的时候,其实是返回了RequestFacade对象,而RequestFacade内部可以根据是否自定义了安全管理器来进行相应的操作,防止开发人员强转Request对象造成不必要的方法泄露。

关于门面模式(外观模式)的详细说明,参考设计模式笔记10:外观模式(Facade Pattern)

2 观察者模式

定义
观察者模式在对象之间定义了一对多的依赖,这样一来,依赖它的对象都会受到通知并自动更新。(接口回调的一种方式,观察者在同一个被观察者对象中注册自己的信息(引用),当被观察者发生变化时,调用观察者的特定方法,告诉观察者。)
Tomcat中的应用
Tomcat中需要对很多组件进行生命周期管理,为此Tomcat抽象了统一的生命周期管理骨架,通过这个骨架将所有需要进行生命周期管理的类都纳入进来管理,而这里的骨架的类图如下:
观察者模式
通过上图我们可以看出Tomcat抽象了一个LifecycleSupport的类,而所有需要生命周期管理的组件通过LifecycleSupport类通知对某个生命周期事件感兴趣的观察者,而所有的观察者都需要实现LifecycleListener。
另外我们需要关注一下LifecycleEvent对象,它里面定义了一个事件源对象,所谓事件源就是事件发生的地方,而在Tomcat的设计中,事件源就是实现了LifeCycle接口的各个需要管理生命周期的组件,LifeCycleSupport关联LifeCycle对象就是为了实现事件源的传递,这样在LifeCycleSupport触发事件的时候,可以通过事件源构建LifecycleEvent.这样以来LifecycleListener就可以通过事件对象获取到事件源,从而做一些与事件源相关的操作。
LifecycleListener 代表的是抽象观察者,它定义一个 lifecycleEvent 方法,这个方法就是当主题变化时要执行的方法。
Lifecycle 接口代表的是抽象主题,它定义了管理观察者的方法和它要所做的其它方法。
LifecycleSupport、LifecycleEvent,它们作为辅助类扩展了观察者的功能。LifecycleEvent 使得可以定义事件类别,不同的事件可区别处理,更加灵活。LifecycleSupport 类代理了主题对多观察者的管理,将这个管理抽出来统一实现,以后如果修改只要修改 LifecycleSupport 类就可以了,不需要去修改所有具体主题,因为所有具体主题的对观察者的操作都被代理给 LifecycleSupport 类了。这可以认为是观察者模式的改进版。
被观察者,有很多方法可以管理观察者,如添加删除观察者,功能类似LifeCycle。观察者主要关注某个事件的触发,如LifecycleListener的lifecycleEvent方法,而这里发生的事件就是LifecycleEvent对象。

关于观察者模式的详细说明,参考设计模式笔记2:观察者模式(Observer Pattern)

3 命令模式

定义
命令模式将请求封装成对象,这可以让你使用不同的请求,队列,或者日志请求来参数化其他对象。命令模式也可以支持撤销操作。
命令模式是一种对象行为型模式,其别名为动作(Action)模式或事务(Transaction)模式。
命令模式是对命令的封装。命令模式把发出命令的责任和执行命令的责任分割开,委派给不同的对象。
每一个命令都是一个操作:请求的一方发出请求要求执行一个操作;接收的一方收到请求,并执行操作。命令模式允许请求的一方和接收的一方独立开来,使得请求的一方不必知道接收请求的一方的接口,更不必知道请求是怎么被接收,以及操作是否被执行、何时被执行,以及是怎么被执行的。
Tomcat中的应用
命令模式在Tomcat中主要是应用在对请求的处理过程中,Tomcat的实现中,根据它支持两种协议AJP和Http,而在具体的IO实现中,又分为Java同步阻赛IO,Java同步非祖塞IO,以及采用APRApache Portable Runtime 支持库,因此Tomcat统一了org.apache.coyote.Processor接口,根据协议和IO实现的不同通过不同的Process子类去实现,Connector作为客户端每次只需要根据具体的协议和IO实现创建对应的Process执行即可。下面我们来看一下命令模式在Tomcat中实现的相关类图:
命令模式
Connector 作为抽象请求者,HttpConnector 作为具体请求者。HttpProcessor 作为命令。Container 作为命令的抽象接受者,ContainerBase 作为具体的接受者。客户端就是应用服务器 Server 组件了。Server 首先创建命令请求者 HttpConnector 对象,然后创建命令 HttpProcessor 命令对象。再把命令对象交给命令接受者 ContainerBase 容器来处理命令。命令的最终是被 Tomcat 的 Container 执行的。命令可以以队列的方式进来,Container 也可以以不同的方式来处理请求,如 HTTP1.0 协议和 HTTP1.1 的处理方式就会不同。

关于命令模式的详细说明,参考设计模式笔记8:命令模式(Command Pattern)

4 责任链模式

定义
职责链模式(Chain of Responsibility Pattern):避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。由于英文翻译的不同,职责链模式又称为责任链模式,它是一种对象行为型模式。
Tomcat中的应用
在 tomcat 中这种设计模式几乎被完整的使用,tomcat的容器设置就是责任链模式,从 Engine 到 Host 再到 Context 一直到 Wrapper 都是通过一个链传递请求。
责任链模式
从上图中,我们可以看到每一个容器都会有一个Pipeline,而一个Pipeline又会具有多个Valve阀门,其中StandardEngine对应的阀门是StandardEngineValve,StandardHost对应的阀门是StandardHostValve,StandardContext对应的阀门是StandardContextValve,StandardWrapper对应的阀门是StandardWrapperValve。这里每一Pipeline就好比一个管道,而每一Valve就相当于一个阀门,一个管道可以有多个阀门,而对于阀门来说有两种,一种阀门在处理完自己的事情以后,只需要将工作委托给下一个和自己在同一管道的阀门即可,第二种阀门是负责衔接各个管道的,它负责将请求传递给下个管道的第一个阀门处理,而这种阀门叫Basic阀门,它是每个管道中最后一个阀门,上面的Standard*Valve都属于第二种阀门。

关于责任链模式的详细说明,参考设计模式笔记18:职责链模式(Chain of Responsibility Pattern)

5 模板方法模式

定义
模板模式在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。模板方法是一种类行为型模式。
模板方法模式是基于继承的代码复用基本技术,模板方法模式的结构和用法也是面向对象设计的核心之一。在模板方法模式中,可以将相同的代码放在父类中,而将不同的方法实现放在不同的子类中。
Tomcat中的应用
java.servlet.GenericServlet定义了模板方法,同时,javax.servlet.http.HttpServlet提供了默认的模板实现,HttpServlet的子类,不直接实现或者override了service方法,类似于doGet,doPost等等。
模板方法模式
关于模板方法模式的详细说明,参考设计模式笔记11:模板方法设计模式(Template Method Pattern)

6 装饰器模式

定义
装饰者模式动态地将责任附加到对象上。想要扩展功能,装饰者提供有别于继承的另一种选择。该模式以对客户端透明的方式扩展对象的功能。利用组合在运行时动态的合成自己想要的对象,这比继承更具弹性,是继承关系的一个替代方案。
Tomcat中的应用
javax.servlet.http.HttpServletRequestWrapper类。
装饰器模式
关于装饰器模式的详细说明,参考设计模式笔记3:装饰者模式(Decorator Pattern)

7 适配器模式

定义
适配器模式将一个类的接口,转换成客户期望的另一个接口。适配器让原本接口不兼容的类可以合作无间。其别名为包装器(Wrapper)。适配器模式既可以作为类结构型模式,也可以作为对象结构型模式。
Tomcat中的应用
CoyoteAdapter
适配器模式
关于适配器模式的详细说明,参考设计模式笔记9:适配器模式(Adapter Pattern)

猜你喜欢

转载自blog.csdn.net/yangzl2008/article/details/48221411
今日推荐