Facade(外觀)模式為子系統中的各類(或結構與方法)提供一個簡明一致的界面,隱藏子系統的復雜性,使子系統更加容易使用。它是為子系統中的一組接口所提供的一個一致的界面
應用:重新進行類的設計,將原來分散在源碼中的類/結構及方法重新組合,形成新的、統一的接口,供上層應用使用。
聽起來有點高端,其實很簡單,用一個簡單的例子說明下
在寫一個簡單的tomcat容器時,需要在一個處理器類ServletProcessor里面把request,response這兩個對象傳遞給Servlet類的service(request, response)方法供servlet開發人員使用:
((Servlet)ServletClass.newInstance()).service(request, response);
這里的傳遞的request和response對象由tomcat開發人員創建,除了實現繼承自javax.sevrlet.request接口和javax.servlet.response接口的方法外它們還有各自的公共方法,
把這樣的對象直接給servlet開發人員存在一個安全隱患,servlet開發人員可以將request,和response對象做向上轉型之后調用它們自己的公共方法,但這些方法在servlet中應該是不可用的! how to awoid this problem?
it's very easy:
我們利用組合的方式分別建立request和response的外觀類
它們的結構大致如下
RequestFacade
public class RequestFacade implements ServletRequest {
private Request request;
public RequestFacade(Request request) {
this.request = request;
}
@Override
public AsyncContext getAsyncContext() {
return request.getAsyncContext();
}
@Override
public Object getAttribute(String arg0) {
return request getAttribute(arg0).;
}
//省略了ServletRequest接口里的眾多方法
}
ResponseFacade
public class ResponseFacade implements ServletResponse {
private Response response;
public ResponseFacade(Response response) {
this.response = response;
}
@Override
public void flushBuffer() throws IOException {
response.flushBuffer();
}
//省略了ServletResponse接口里的眾多方法
}
然后通過request和response初始它們的外觀類對象,并把它們的外觀類對象傳給Service()方法即可:
RequestFacade requestFacade = new RequestFacade(request);
ResponseFacade responseFacade = new ResponseFacade(response);
try {
((Servlet)ServletClass.newInstance()).service(requestFacade, responseFacade);
} catch (InstantiationException | IllegalAccessException | ServletException | IOException e) {
PubUtil.error("ServletProcessor --- process3 ---Exception"+e.getMessage());
return;
}
RequestFacade 外觀類包含類request,并且和request類都繼承了ServletRequest接口,所以servlet程序員就可以通過外觀類來調用ServletRequest接口的所有方法,同時有效屏蔽了request類自己的公共方法。ResponseFacade具有同樣的功能。