深入理解Java外观模式
文章目录
- 详解Java设计模式之外观模式
- 案例引入
- 分析
- 外观模式
- 定义
- 模式结构类图
- 包含角色
- 典型代码
- 案例分析
- 类图分析
- 代码
- 抽象外观类
- 类图
- 典型代码
- 外观模式与单例模式的联用
- 外观模式优点
- 外观模式的缺点
- 外观模式的适用条件
详解Java设计模式之外观模式
案例引入
-
为一个复杂的子系统提供一个简单的入口
分析
-
一个客户类和多个业务类进行交互,而这些需要交互的业务类经常会作为一个整体出现。
-
引入一个新的外观类(Facade)来负责多个业务类或者说是子系统,而客户类只需要与外观类进行交互
-
为了业务类的调用提供一个统一的入口,简化了类与类之间的交互‘
-
一个子系统的外部与其内部的通信通过一个统一的外观类进行,外观类将客户类与子系统的内部复杂性分隔开,使得客户类只需要与外观角色打交道,而不需要与子系统内部的很多对象打交道
- 没有外观类:每个客户类需要和多个子系统之间进行复杂的交互,系统的耦合度很大
- 引入外观类:客户类只需要直接与外观类交互,客户类与子系统之间原有的复杂引用关系由外观类来实现,从而降低了系统的耦合度
外观模式
定义
外观模式:为子系统的一组接口提供一个统一的入口,外观模定义一个高层的接口,这个接口使得子系统更加统一使用。
Facade Pattern: Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use.
- 外观模式属于对象结构型模式
- 又称为门面模式
- 是***迪米特法则***的一种具体实现
- 通过引入一个新的外观角色来降低原有系统的复杂度,同时降低客户类与子系统系统之间的耦合度。
- 所指的子系统是一个广义的概念,他可以是一个类,一个功能模块,系统的一个组成部分或者一个完整的系统。
模式结构类图
包含角色
- Facade 外观角色
- SubSystem 子系统角色
典型代码
-
subsystem
public class SubSystemA { public void methodA() { //业务实现代码 } } public class SubSystemB { public void methodB() { //业务实现代码 } } public class SubSystemC { public void methodC() { //业务实现代码 }
-
Facade
public class Facade { private SubSystemA obj1 = new SubSystemA(); private SubSystemB obj2 = new SubSystemB(); private SubSystemC obj3 = new SubSystemC(); public void method() { obj1.methodA(); obj2.methodB(); obj3.methodC(); }
案例分析
某软件公司要开发一个可应用于多个软件的文件加密模块,该模块可以对文件中的数据进行加密并将加密之后的数据存储在一个新文件中,具体的流程包括3个部分,分别是读取源文件、加密、保存加密之后的文件,其中,读取文件和保存文件使用流来实现,加密操作通过求模运算实现。这3个操作相对独立,为了实现代码的独立重用,让设计更符合单一职责原则,这3个操作的业务代码封装在3个不同的类中。
现使用外观模式设计该文件加密模块。
类图分析
代码
见我的gitee链接:
外观模式的代码Gitee链接
结果
读取文件,获得明文:
zzx is my son !
数据加密,将明文转换为密文:
331403442436545
保存密文,写入文件。
(1) FileReader:文件读取类,充当子系统类
(2) CipherMachine:数据加密类,充当子系统类
(3) FileWriter:文件保存类,充当子系统类
(4) EncryptFacade:加密外观类,充当外观类
(5) Client:客户端测试类
抽象外观类
类图
典型代码
public abstract class AbstractEncryptFacade {
public abstract void fileEncrypt(String fileNameSrc, String fileNameDes);
}
<?xml version="1.0"?>
<config>
<className>designpatterns.facade.NewEncryptFacade</className>
</config>
public class NewEncryptFacade extends AbstractEncryptFacade {
private FileReader reader;
private NewCipherMachine cipher;
private FileWriter writer;
public NewEncryptFacade() {
reader = new FileReader();
cipher = new NewCipherMachine();
writer = new FileWriter();
}
public void fileEncrypt(String fileNameSrc, String fileNameDes) {
String plainStr = reader.read(fileNameSrc);
String encryptStr = cipher.encrypt(plainStr);
writer.write(encryptStr,fileNameDes);
}
}
public class Client {
public static void main(String args[]) {
AbstractEncryptFacade ef;
ef = (AbstractEncryptFacade)XMLUtil.getBean();
ef.fileEncrypt("src//designpatterns//facade//src.txt","src//designpatterns //facade//des.txt"); }
}
外观模式与单例模式的联用
外观模式优点
- 对客户端屏蔽了子系统组件,减少了客户端所需处理的对象数目,并使得子系统使用起来更加容易
- 实现了子系统与客户端之间的松耦合关系,这使得子系统的变化不会影响到调用它的客户端,只需要调整外观类即可
- 子系统的内部变化不会影响到外观对象,一个子系统的修改对其他子系统也没有任何影响
外观模式的缺点
- 不能很好地限制客户端直接使用子系统类,如果对客户端访问子系统类做太多的限制则减少了可变性和灵活性
- 如果设计不当,增加新的子系统可能需要修改外观类的源代码,违背了开闭原则
外观模式的适用条件
- 要为访问一系列复杂的子系统提供一个简单入口
- 客户端程序与多个子系统之间存在很大的依赖性
- 在层次化结构中,可以使用外观模式的定义系统中每一层的入口,层与层之间不直接产生联系,而是通过外观类建立联系,降低层之间的耦合度
上一篇: 理解桥接、适配器和外观模式:三大设计模式的区分解析
下一篇: 外观模式:简化接口,统一编程体验