《深刻剖析Tomcat》(How Tomcat Works),第二章。設計模式
建立 Request
和 Response
分別實現 ServletRequest
和 ServletResponse
,而後將這兩個對象傳給實現了 Servlet
接口的 PrimitiveServlet
類的service方法。安全
下面代碼中的 request 和 response 除了實現 ServletRequest
和 ServletResponse
接口中的方法,還分別自定義了 getUri 和 sendStaticResource 方法,若是將他們向上轉爲 ServletRequest
和 ServletResponse
,那麼在 PrimitiveServlet 中若是被向下轉爲 Request 和 Response,則能夠調用 getUri 和 sendStaticResource 方法,這被認爲是不安全的。ui
Request request = ... Response response = ... servlet = (Servlet) myClass.newInstance(); servlet.service((ServletRequest) request, (ServletResponse) response);
若是將 getUri 和 sendStaticResource 聲明爲私有,則能夠防止在 servlet 中被調用,可是在其餘可能被安全地調用的地方也不能用了,不能夠。若是給方法以默認訪問權限,則只能在同一個包中訪問,這個被認爲是能夠的,可是不最好,最優雅的方式是經過 facade 類。this
具體作法是定義 RequestFacade 和 ResponseFacade 兩個類,分別實現 ServletRequest 和 ServletResponse,同時定義私有成員變量 Request 和 Response,而且方法的實現調用 Request 和 Response 的實現。而後,將 RequestFacade 和 ResponseFacade 上轉爲 ServletRequest 和 ServletResponse 傳給 servlet 的 service 方法,這樣即便在 servlet 中被下轉爲 RequestFacade 和 ResponseFacade,也不能訪問私有成員變量對象中的方法。既用了 Request 和 Response 的實現,又能防止其中自定義的方法被不合理的訪問。spa
類圖以下:設計
代碼:code
public class RequestFacade implements ServletRequest { private ServleLRequest request = null; public RequestFacade(Request request) { this.request = request; } /* implementation of the ServletRequest*/ public Object getAttribute(String attribute) { return request.getAttribute(attribute); } ... } // ResponseFacade相似 RequestFacade requestFacade = new RequestFacade(request); ResponseFacade responseFacade = new ResponseFacade(response); try { servlet = (Servlet) myClass.newInstance(); servlet.service((ServletRequest) requestFacade,(ServletResponse)responseFacade); }
下面是Facade模式的一些內容,與上面的用法不太同樣。對象
定義接口
外觀模式(Facade),爲子系統中的一組接口提供一個一致的界面,此模式定義了一個高層接口,這個接口使得這一子系統更加容易使用。[DP]ip
如下來自維基百科
The facade pattern is typically used when:(外觀模式的典型用法)
a simple interface is required to access a complex system; (須要簡單的接口去訪問複雜的系統)
the abstractions and implementations of a subsystem are tightly coupled;(子系統的抽象和實現是緊密耦合的)
need an entry point to each level of layered software; or(須要一個入口去訪問分層軟件的每一層)
a system is very complex or difficult to understand.(一個複雜的,難以理解的系統)
大話設計模式中基金與股票的例子挺好的,這幅圖也很好:
下面是維基百科上的示例代碼,Java版:
/* Complex parts */ class CPU { public void freeze() { ... } public void jump(long position) { ... } public void execute() { ... } } class Memory { public void load(long position, byte[] data) { ... } } class HardDrive { public byte[] read(long lba, int size) { ... } } /* Facade */ class ComputerFacade { private CPU processor; private Memory ram; private HardDrive hd; public ComputerFacade() { this.processor = new CPU(); this.ram = new Memory(); this.hd = new HardDrive(); } public void start() { processor.freeze(); ram.load(BOOT_ADDRESS, hd.read(BOOT_SECTOR, SECTOR_SIZE)); processor.jump(BOOT_ADDRESS); processor.execute(); } } /* Client */ class You { public static void main(String[] args) { ComputerFacade computer = new ComputerFacade(); computer.start(); } }
參考:
大話設計模式第12章 外觀模式
How Tomcat Works, 第二章