《深刻剖析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, 第二章