关于IBM的Tomcat的设计模式中的门面模式的某些错误1

关于IBM的Tomcat的设计模式中的门面模式的某些错误1

在学习tomcat的代码中,参考了 许 令波2010年 发表在IBM的Tomcat 设计模式,他的第一版(Tomcat的工作原理)确实说得很精彩,我受益无穷,非常感谢。作为一个思维严谨的设计人员,也有点难理解,因此我特意去看代码帮助理解,翻查了Tomcat 5.0 trunk版本到Tomcat 9.0.8 的版本,然后我就发现了他的门面模式的 类图是在Tomcat 4而不是在所使用基础版本Tomcat 5 上做分析的,很多类图是错误,因此我写了这篇文章,希望能跟大家一起讨论学习。


门面设计模式的类图

Request门面设计模式类图
在IBM技术博客上它的类图是这样的

Tomcat 9 的<code>Request</code>和<code>RequestFacade</code> 的类图
而实际上是这样的,我这里展示的是Tomcat 9 的版本的类图。这里就有人会问了IBM那篇是写的是Tomcat 5版本的RequestRequestFacade类图.很好,我因此也去翻阅了5版本的类图,发现是下面这样的.
Tomcat 5 的Request和 RequestFacade 类图
你们会发现它跟9版本的区别就是RequestFacade类多了个SuppressWarnings的标志,准确来说是@SuppressWarnings("deprecation") 注释,这个注释的意思是抑制过时的警告.这是因为Tomcat 6开始为了要兼容Servlet 2.1 版本的API,而开始增加的注释.
回到正题,他们有什么不同呢,而新版本中他们的先进之处在于哪里呢.
首先需要说明的是不管是Tomcat 5或者是Tomcat 9 都没发现HttpRquestFacade这个类,因此可以确认的是Tomcat 组织已经从5开始把它开消除了,简化了,好处当然是能够让复杂度减低了。
接着我们继续经行对比。ServletRequestHttpServletRequest依然是接口的设计,作为标准来让类去实现。没有了Request接口和HttpRequest接口,而取代他们的是Request实体类,而该实体类是和RequestFacade一样实现了HttpServletRequest

RequestFacade实现类图:
RequestFacade接口实现图
Request的实现类图:
Request的实现类图:
从新的类图我们可以看到一个新的简单的门面模式,同样实现某种协议(接口)然而Facade作为门面直接被外部访问;从代码上来看RequestFacadeRequest实现了基于ava.security.PrivilegedAction权限的final class 的权限类,该权限功能是从Tomcat 5 开始使用的,使用final class 的原因是因为子类不能继承覆盖,在编译完以后已经把地址引用和装载都完成了,这让其他的程序无法篡改,这个功能在Tomcat 4 中是CoyoteRequest中实现,先说明一下在Tomcat 5 开始该 CoyoteRequest 改名为Request 并独立放在org.apache.coyote.Request 中,而且他把很多功能迁移到了 RequestFacade 为什么要迁移到门面模式的门面中去呢?具体的说明我会在下篇中详细说明,现在我简单总结就是更好的实现安全权限的控制和更好的内存管理,并让结构更简单化。
最后一点门面模式是怎么应用的呢?这一点在IBM 的文章没说明,我这里先贴出Tomcat 5 的版本实现代码


    private HttpServletRequest applicationRequest = null;
   /**
     * The facade associated with this request.
     */
    protected RequestFacade facade = null;
    /**
     * @return the <code>ServletRequest</code> for which this object
     * is the facade.  This method must be implemented by a subclass.
     */
    public HttpServletRequest getRequest() {
        if (facade == null) {
            facade = new RequestFacade(this);
        }
        if (applicationRequest == null) {
            applicationRequest = facade;
        }
        return applicationRequest;
    }

这就是Tomcat 5 后版本的HTTP 的Request 门面模式,当Catalina 的 StandardEngine 创建出了 Request 后,当他需要给Servlet 传参数的时候就可以直接使用 getRequest 给出 ServletRequest 或者 它的子类 HttpServletRequest 了 。
然后我给出Tomcat 4 版本的门面模式的调用,这里非常的复杂而且和IBM 给出的不一样,我需要重新给出该版本Catalina 的 StandardEngine实际使用的Request 门面模式类图出来。
Tomcat4实际的<code>Request</code> 门面模式类图
从类图中可以分析出其实Catalina 使用的是 Coyote 项目的 CoyoteRequestFacadeCoyoteRequest ,他们的调用模式也是通过 getRquest 的方式调用,下面是代码。


    /**
     * The facade associated with this request.
     */
    protected CoyoteRequestFacade facade = null;

    /**
     * Return the <code>ServletRequest</code> for which this object
     * is the facade.  This method must be implemented by a subclass.
     */
    public ServletRequest getRequest() {
        if (facade == null) {
            facade = new CoyoteRequestFacade(this);
        }
        return (facade);
    }

好了,对于懒人的我终于把IBM的设计模式的门面模式写出来了,里面肯定有错别字吧,不管了太久没写了,让我瞎扯一堆吧!而且给自己埋下很多很多的需要继续填补,继续写下去的文章来应承诺了。下一篇我可能会写 新版本的Request 和 RequestFacade 是如何分工的和CoyoteRequest是什么关系呢?的代码分析给写出来,或者继续把设计模式那篇文章在Tomcat 5 后的新版本的结构变成怎样的呢?的博文写出来。请大家期待下一期吧。


猜你喜欢

转载自blog.csdn.net/lzcaqde/article/details/80806414