Facade(门面模式)
组成角色
门面(Facade)角色:将客户端的请求委派到相应的子系统。(单例操作,但不是只有一个门面)
注意:不能向系统加入新的行为。
子系统(SubSystem)角色:
动机:
用户只需要直接与Facade角色交互,用户与子系统之间的复杂关系由外观角色来实现,降低系统耦合。
Facade模式:为子系统中的一组接口提供一个统一的接口,Facade定义了一个更高层的接口,使子系统更加容易使用。
优点与缺点
1、 对客户屏蔽子系统组件,减少客户处理的对象数目并使得子系统使用更加容易。客户代码变得更简单。
2、 实现了子系统与客户之间的松耦合关系。
3、 降低了大型软件系统中的编译依赖性,并简化了系统在不同平台之间的移植过程。
4、 只是提供了一个访问子系统的统一入口,并不影响用户直接使用子系统类。
缺点:
1、 不能很好的限制客户使用子系统类。如果对客户访问子系统类做太多的限制则减少了可变性和灵活性。
2、 增加新的子系统可能需要修改外观类或客户端源代码,违背“开闭原则”(考虑引入抽象外观类)。
适用环境
1、 当要为一个复杂子系统提供一个简单接口时可以使用外观模式。
2、 客户程序与多个子系统之间存在很大的依赖性。可以提子系统的独立性和可移植性。
3、 使用外观模式定义系统中每一层的入口,层与层之间不直接产生联系,面通过外观类建立联系,降低层之间的耦合度。
故事说明
FACADE—我有一个专业的Nikon相机,我就喜欢自己手动调光圈、快门,这样照出来的照片才专业,但MM可不懂这些,教了半天也不会。幸好相机有Facade设计模式,把相机调整到自动档,只要对准目标按快门就行了,一切由相机自动调整,这样MM也可以用这个相机给我拍张照片了。
门面模式:外部与一个子系统的通信必须通过一个统一的门面对象进行。门面模式提供一个高层次的接口,使得子系统更易于使用。每一个子系统只有一个门面类,而且此门面类只有一个实例,也就是说它是一个单例模式。但整个系统可以有多个门面类。
/** 读取文件 */ public class FileReader { public String read(){ //这个方法有一大堆逻辑 System.out.println("读取文件内容:helloworld"); return "helloworld"; } }
/** 文件加密类 */ public class FileEncoder { public String encoder(String content){ //这个方法有一大堆逻辑 content = "**"+content+"**"; System.out.println("加密文件内容:"+ content); return content; } }
/** 写入文件 */ public class FileWriter { public void write(String content){ //这个方法有一大堆逻辑 System.out.println("写入文件内容:"+ content); } }
/** * 例子,把文件内容读入,加密,再写入 */ public class FileFacade { private FileReader fileReader; private FileEncoder fileEncoder; private FileWriter fileWriter; private static final FileFacade fileFacade = new FileFacade(); private FileFacade(){ fileReader = new FileReader(); fileEncoder = new FileEncoder(); fileWriter = new FileWriter(); } public static FileFacade getInstance(){ return fileFacade; } public void fileEncode(){ String content = fileReader.read(); content = fileEncoder.encoder(content); fileWriter.write(content); } public static void main(String[] args) { //完成一个动作:要求把文件内容读入,加密,再写入 //方式一不用外观,用户需要自己定义所需要对象,和操作 FileReader fileReader = new FileReader(); FileEncoder fileEncoder = new FileEncoder(); FileWriter fileWriter = new FileWriter(); String content = fileReader.read(); content = fileEncoder.encoder(content); fileWriter.write(content); System.out.println("-------------方式二----------------"); //给用户定义一个Facade门面,让客户端,软量级操作; FileFacade fileFacade = FileFacade.getInstance(); fileFacade.fileEncode(); } }
读取文件内容:helloworld
加密文件内容:**helloworld**
写入文件内容:**helloworld**
-------------方式二(门面操作)----------------
读取文件内容:helloworld
加密文件内容:**helloworld**
写入文件内容:**helloworld**