外观模式定义
外观模式(Facade Pattern)提供了一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用。
外观模式允许我们让客户和子系统之间避免紧耦合,它遵守“最少知识”原则。这个原则希望我们在设计中,不要让太多的类耦合在一起,免得修改系统中一部分,会影响到其他部分。如果许多类之间相互依赖,那么这个系统就会变成一个易碎的系统,它需要花许多成本维护,也会因为太复杂而不容易被其他人了解。
外观模式对客户屏蔽子系统组件,减少了客户处理的对象数目,使得子系统使用起来更加容易。
外观模式结构图
图中:
Facade表示外观角色,客户端可以调用这个方法,此角色知道相关的(一个或多个)子系统的功能和责任,在正常情况下,将所有从客户端发来的请求委派到相应的子系统去,传递给相应的子系统对象处理;
Subsystem表示子系统角色,一个系统可以同时有一个或多个子系统,每一个子系统都不是一个单独的类,而是一个类的集合,它实现子系统的功能,每一个子系统都可以被客户端直接调用,或者被外观角色调用,它处理由外观类传过来的任务,子系统并不知道外观的存在,对于子系统而言,外观仅仅是另外一个客户端而已。
外观模式实例——文件加密
实例说明
某系统需要提供一个文件加密模块,加密流程包括三个操作,分别是读取源文件、加密、保存加密之后的文件。读取文件和保存文件使用流来实现,这三个操作相对独立,其业务代码封装在三个不同的类中。现在需要提供一个统一的加密外观类,用户可以直接使用该加密外观类完成文件的读取、加密和保存三个操作,而不需要与每一个类进行交互,使用外观模式设计该加密模块,要求编程模拟实现。
实例类图
实例类图中与外观模式结构图对应的类主要有:
实例代码
EncryptFacade.java:
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); } }
|
FileReader.java:
import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException;
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(); } }
|
CipherMachine.java:
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; } }
|
FileWriter.java:
import java.io.FileOutputStream; import java.io.FileNotFoundException; import java.io.IOException;
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("文件操作错误!"); } } }
|
Client.java:
class Client { public static void main(String args[]) { EncryptFacade ef = new EncryptFacade(); ef.fileEncrypt("src/src.txt","src/des.txt"); } }
|
运行结果
Console输出:
src.txt和des.txt文件中的内容为:
附加描述
在本实例中,对src文件夹下的文件src.txt中的数据进行加密,该文件的内容为“Hello world!”,加密之后将密文保存到src文件夹下的另一个文件des.txt中,程序运行后保存在文件中的密文为“233364062325”。在加密类CipherMachine中,采用求模运算对明文进行加密,将明文中的每一个字符除以一个整数(本例中为7,可以由用户自行设置)后取余数作为密文。
后话
Facade模式的思想简单,但是用处甚广。