定义
门面模式(Facade Pattern)也叫外观模式,它隐藏系统的复杂性,并向客户端提供一个可以访问系统的接口。这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性,为子系统中的一组接口提供了一个统一的高层访问接口,这个接口使得子系统更容易被访问或使用。
基本简介
(1)客户端
通过调用Facede来完成要实现的功能。
(2)门面角色
门面模式的核心。它被客户角色调用,它熟悉子系统的功能。内部根据客户角色的需求预定了几种功能的组合。
(3)子系统
实现了子系统的功能。它对客户角色和Facade时未知的。它内部可以有系统内的相互交互,也可以由供外界调用的接口。
示例
我们拿生活中电脑开机为例
结构
(1.1)子系统
public class Cpu { private Logger logger = Logger.getLogger(Cpu.class.getName()); /** * 释放 */ public void freeze() { logger.info("cpu freeze.."); } /** * 执行 */ public void execute() { logger.info("cpu execute.."); } }
public class HardDrive { private Logger logger = Logger.getLogger(HardDrive.class.getName()); public void read() { logger.info("hardDrive read.."); } }
public class Memory { private Logger logger = Logger.getLogger(Memory.class.getName()); public void load() { logger.info("memory load.."); } }
(1.2)门面
public class Computer { private Cpu cpu; private Memory memory; private HardDrive hardDrive; public Computer() { cpu = new Cpu(); memory = new Memory(); hardDrive = new HardDrive(); } public void start() { cpu.freeze(); hardDrive.read(); memory.load(); cpu.execute(); } }
(1.3)客户端
这里我们用单元测试入口作为调用端
public class facadeClient { @Test public void testFacadeDesign() { Computer facade = new Computer(); facade.start(); } }
(1.4)客户端调用结果
门面模式在Tomcat中的使用
如下是查看tomcat源码中的类引用关系得到的结果
Request对象中的很多方法都是内部组件之间相互交互时使用的,比如setComet、setRequestedSessionId等方法(这里就不一一列举了)。这些方法并不对外部公开,但是又必须设置为public,因为还需要跟内部组件之间交互使用。最好的解决方法就是通过使用一个Facade类,将与内部组件之间交互使用的方法屏蔽掉,只提供给外部程序感兴趣的方法。
如果不使用Facade类,直接传递的是Request对象和Response对象,那么熟悉容器内部运作的程序员可以分别把ServletRequest和ServletResponse对象向下转换为Request和Response,并调用它们的公共方法。比如拥有Request对象,就可以调用setComet、setRequestedSessionId等方法,这会危害安全性。
小结
门面模式的用意是为子系统提供一个集中化和简化的沟通管道,而不能向子系统加入新的行为。门面模式的优点:
1.松散耦合
门面模式松散了客户端与子系统的耦合关系,让子系统内部的模块能更容易扩展和维护。
2.简单易用
门面模式让子系统更加易用,客户端不再需要了解子系统内部的实现,也不需要跟众多子系统内部的模块进行交互,只需要跟门面类交互就可以了。
3.更好的划分访问层次
通过合理使用Facade,可以帮助我们更好地划分访问的层次。有些方法是对系统外的,有些方法是系统内部使用的。把需要暴露给外部的功能集中到门面中,这样既方便客户端使用,也很好地隐藏了内部的细节。