外观模式在开源代码中的应用
16lz
2021-01-22
外观模式的作用:为多个复杂的子系统提供一个一致的接口,使这些子系统更加容易被访问,且不会暴露过多的底层实现细节。
案例
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 的底层实现细节,降低了底层方法被调用出错的风险
更多相关文章
- 构造方法的参数太多,如何解决?
- 面试官:为什么静态方法不能调用非静态方法和变量?
- ConcurrentHashMap之size()方法
- 为什么不推荐使用finalize方法,来看看对垃圾回收有什么影响吧
- 阿里的OceanBase数据库世界第一,底层原来是用了Paxos协议