java的设计模式 - 外观模式(Facade)

目的

看脸模式目的很简单,就是给用户留个好印象,不想让用户关注系统中的具体细节,关注系统的外表(暴露出来的接口)就好了。一些 GUI 的菜单也好,SDK 也好或多或少也会用到这种思想。这更多的是一种思想,也没有说一定这样实现才是外观模式的 。参考维基百科的例子,电脑有 cpu、内存、磁盘等组成,cpu 有逻辑运算部分、有取指令部分;内存要负责存储指令数据;磁盘要控制磁道等等,这些都不是用户关心的,用户需要一个开机按钮罢了。

在《深入剖析 Tomcat》(英文名:《How tomcat works》)中也介绍了一下 Tomcat 中 Facade 模式的使用,下面来看看Tomcat 中 Facade 模式吧

Tomcat 中的 Facade 模式

Tomcat 中的 Facade 模式弄得有点像代理模式的。场景是这样的,Tomcat 中 Request 除了实现了 ServletRequest 接口外,还会有额外的一些函数,而这些函数需要被其他类调用,但这些方法不应该暴露给上层,因为上层应该专注于 ServletRequest 的实现。于是在 Tomcat 中会使用 Facade 模式了。

原来的 process 处理请求是这样的

public class ServletProcess {
    public void process(Request request, Response response){
        //....
        servlet = (Servlet) myClass.newInstance();
        servlet.service((ServletRequest) request, (ServletResponse) response);
    }
}

而使用 Facade 后是这样

public class ServletProcess {
    public void process(Request request, Response response){
        //....
        RequestFacade requestFacade = new RequestFacade(request);
        ResponseFacade responseFacade = new ResponseFacade(response);
        servlet = (Servlet) myClass.newInstance();
        servlet.service((ServletRequest) requestFacade, (ServletResponse) responseFacade);
    }
}

为了达到这种效果,RequestFacade 使用了类似代理模式的实现方式。

public class RequestFacade implements HttpServletRequest {

   private ServletRequest request;

    public RequestFacade(ServletRequest request) {
        this.request = request;
    }

    @Override
    public String getAuthType() {
        return request.getAuthType();
    }
}

对象里有个 ServletRequest 对象,而 RequestFacade 的所有方法都会委托给 ServletRequest 调用。

当然,逐个函数手动写委托调用好烦,好浪费时间的,我推荐使用了 lombok ,像是魔法一样,轻轻一个 @Delegate 就完事了

public class RequestFacade implements HttpServletRequest {
    
    @Delegate
    private ServletRequest request;
}

用 UML 分析是这样的,未使用 Facade 模式前

使用 Facade 模式之后

posted @ 2019-04-01 09:55  JOJO_2046  阅读(1407)  评论(0编辑  收藏  举报