外观模式的作用:为多个复杂的子系统提供一个一致的接口,使这些子系统更加容易被访问,且不会暴露过多的底层实现细节。

 

案例

Tomcat 的 catalina.jar 中的 RequestFacade 和 ResponseFacade 两个类就使用了外观模式。
servlet-api 中定义了 HttpServlet 抽象类,类中的定义了处理 http 协议的 get、post、delete... 等请求,返回处理结果,对应需要实现方法 doGet、doPost、doDelete...这些方法有两个共同的参数:HttpServletRequest、HttpServletResponse

public abstract class HttpServlet extends GenericServlet {
   protected void doGet(HttpServletRequest req, HttpServletResponse resp)        throws ServletException, IOException{        String protocol = req.getProtocol();        String msg = lStrings.getString("http.method_get_not_supported");        if (protocol.endsWith("1.1")) {            resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);        } else {            resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);        }    }    ...}

 

HttpServlet 的方法中的 HttpServletRequest、HttpServletResponse 这两个参数实际传入的是 RequestFacade 和 ResponseFacade。图片

以 RequestFacade 为例,RequestFacade 通过构造方法持有 Request 对象

public class RequestFacade implements HttpServletRequest {    protected Request request = null;     public RequestFacade(Request request){        this.request = request;    }    //后面的方法使用 request 对象进行处理    ...}

 

Request 对象有一个转换为 RequestFacade 对象的方法

public class Request implements HttpServletRequest {    public HttpServletRequest getRequest() {        if (this.facade == null) {            this.facade = new RequestFacade(this);        }        return this.facade;    }
   //与tomcat底层组件进行交互}

 

Request 对象的 getRequest 方法 和 Response 对象的 getResponse 方法,在这里被调用

final class StandardWrapperValve extends ValveBase {
   public final void invoke(Request request, Response response) throws IOException, ServletException {        ...        filterChain.doFilter(request.getRequest(), response.getResponse());        ...    }
}

 

为啥要把Request 和Response 包装 RequestFacade 和 ResponseFacade?

  • RequestFacade 和 ResponseFacade 只提供应用程序所需要的 API
  • Request、Response 偏底层,且交互复杂,Facade 隐藏了 Request 和 Response 的底层实现细节,降低了底层方法被调用出错的风险


图片


更多相关文章

  1. 构造方法的参数太多,如何解决?
  2. 面试官:为什么静态方法不能调用非静态方法和变量?
  3. ConcurrentHashMap之size()方法
  4. 为什么不推荐使用finalize方法,来看看对垃圾回收有什么影响吧
  5. 阿里的OceanBase数据库世界第一,底层原来是用了Paxos协议

随机推荐

  1. Druid数据库连接池就是这么简单
  2. Ruby和Python哪个更强大?学习分析
  3. Java面试题全集(12)
  4. 面试官:什么是CSRF?(你的钱为什么被转走,这篇
  5. 2020年5A PMP 经验分享
  6. 静态链表
  7. 栈和队列就是这么简单
  8. 解读容器的 2020:寻找云原生的下一站
  9. JVM中一个小知识点:深堆和浅堆的认识
  10. Linux网络基础概念