一、外观模式
外观(Facade)模式又叫作门面模式,属于对象结构型模式。
定义:是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。
使用频率:5星
模式结构:
外观(Facade)模式包含以下主要角色:
1、外观(Facade)角色:为多个子系统对外提供一个共同的接口。
2、子系统(Sub System)角色:实现系统的部分功能,客户可以通过外观角色访问它。
3、客户(Client)角色:通过一个外观角色访问各个子系统的功能。
外观模式结构图:
优点:
外观模式是“迪米特法则”的典型应用,其有以下优点:
1、降低了子系统与客户端之间的耦合度,使得子系统的变化不会影响调用它的客户类。
2、对客户屏蔽了子系统组件,减少了客户处理的对象数目,并使得子系统使用起来更加容易。
3、降低了大型软件系统中的编译依赖性,简化了系统在不同平台之间的移植过程,因为编译一个子系统不会影响其他的子系统,也不会影响外观对象。
缺点:
1、不能很好地限制客户使用子系统类,很容易带来未知风险。
2、增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”。
应用场景:
1、对分层结构系统构建时,使用外观模式定义子系统中每层的入口点可以简化子系统之间的依赖关系。
2、当一个复杂系统的子系统很多时,外观模式可以为系统设计一个简单的接口供外界访问。
3、当客户端与多个子系统之间存在很大的联系时,引入外观模式可将它们分离,从而提高子系统的独立性和可移植性。
二、外观模式实例之文件加密
1.实例说明
某系统需要提供一个文件加密模块,加密流程包括读取源文件、加密、保存三个步骤。读取文件和保存文件使用流来实现,这三个操作相对独立,其业务代码封装在三个类中。现需要提供一个统一的加密外观类,用户可以直接使用该加密外观类完成文件的读取、加密和保存,而不需要与每一个类进行交互,使用外观模式设计该加密模块。
2.实例类图
3.实例代码
本例中EncryptFacade充当外观类,FileReader、CipherMachine和FileWrier充当子系统类。
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
//加密外观类:外观类
class EncryptFacade{
private FileReader reader;
private CipherMachine cipher;
private FileWriter writer;
public EncryptFacade(){
reader=new FileReader();
cipher=new CipherMachine();
writer=new FileWriter();
}
public void fileEncrypt(String fileNameSrc,String fileNameDes){
String plainStr = reader.read(fileNameSrc);
String encryptStr = cipher.encrypt(plainStr);
writer.write(encryptStr,fileNameDes);
}
}
//文件读取类:子系统类
class FileReader{
public String read(String fileNameSrc){
System.out.println("读取文件,获取明文");
StringBuffer sb = new StringBuffer();
try{
FileInputStream inFS = new FileInputStream(fileNameSrc);
int data;
while ((data=inFS.read())!=-1){
sb = sb.append((char) data);
}
inFS.close();
} catch (FileNotFoundException e) {
System.out.println("文件不存在!");
} catch (IOException e) {
System.out.println("文件操作错误!");
}
return sb.toString();
}
}
//数据加密类:子系统类
class CipherMachine{
public String encrypt(String plainText){
System.out.println("数据加密,将明文转换为密文");
String es="";
for(int i=0;i<plainText.length();i++){
String c = String.valueOf(plainText.charAt(i)%7);
es += c;
}
return es;
}
}
//文件保存类:子系统类
class FileWriter{
public void write(String encryptStr,String fileNameDes){
System.out.println("保存密文,写入文件");
try{
FileOutputStream outFS = new FileOutputStream(fileNameDes);
outFS.write(encryptStr.getBytes());
outFS.close();
} catch (FileNotFoundException e) {
System.out.println("文件不存在!");
} catch (IOException e) {
System.out.println("文件操作错误!");
}
}
}
客户端测试代码:
public class Client {
public static void main(String[] args) {
EncryptFacade ef = new EncryptFacade();
ef.fileEncrypt("src.txt","des.txt");//src.txt请手动创建好
}
}
运行结果:
读取文件,获取明文
数据加密,将明文转换为密文
保存密文,写入文件
可以看出外观模式或称为门面模式更适合一点,将“门”里面的代码在封装一次,通过“门面”将子系统接口统一,外面的人不用了解门里面的情况,只要看门面就能得到需要的数据。
参考文献
【1】外观模式(Facade模式)详解
【2】设计模式实训教程(第2版) 刘伟 编著 清华大学出版社