通过本文将学习到
1、前言
2、外观模式的概念
3、外观模式的UML
4、外观模式的实现
5、外观模式的优缺点及使用场景
6、总结
外观模式是一种使用频率非常高的结构型设计模式,它通过引入一个外观角色来简化客户端与子系统之间的交互,为复杂的子系统调用提供一个统一的入口,使子系统与客户端的耦合度降低,且客户端调用变得更加方便。简而言之,言而简之就是说外观模式是用来简化调用操作的!
吐槽一下,今天发工资了。难受啊,马飞!说好的月薪过万了。哈哈,果然还是自己太菜了。接下来请好好加油FIGTING。Linux也得买菜做饭嘞!就算不做,起码得点外卖吧!
外观模式:为子系统中的一组接口提供一个统一的入口。外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
抄一段例子:不知道大家有没有比较过自己泡茶和去茶馆喝茶的区别,如果是自己泡茶的话,需要准备茶叶,茶具,和开水。而去茶馆的话就只需要说老子要一碗冰红茶就OK了,服务员会帮你准备好一切。其他如果泡茶的过程我们就不用考虑了。贼方便。
所以在软件过程中为了完成一项比较复杂的功能的时候,一个客户类需要和多个业务类进行交互,而这些需要交互的业务类,也通常以一个整体出现,由于涉及的类比较多,导致使用时代码较为复杂,此时特别需要象茶馆服务员这样的关键人物出现他来帮我泡茶岂不美滋滋?。外观模式就是干这活,简化客户端和其他各种各样的业务接口打交道的麻烦。如果让客户端和每个业务类交互则会使软件耦合度成倍的增长。
画个图比较好了解
:没用服务员,全靠自己手动操作。我只画出了帅哥威和龙井的,还可以喝,铁观音啥的。
用外观模式,全部让店小二去弄,我不管,反正就是要喝冰红茶。
外观模式的UML图是我觉得除开单例模式中最简单的一种。也就两个角色!
Facade(外观角色):这是核心类,在客户端可以调用他的方法,在外观角色中可以知道相关的子系统的功能和责任;在正常情况下,他将所有从客户端的请求委派到各个相应的子系统,传递给相应的子系统对象处理
SubSystem(子系统角色):在软件系统中可以有一个或多个子系统角色,每一个子系统可以不是一个单独的类,而是一个类的集合,它实现子系统的功能;每一个子系统都可以被客户端直接调用,或者被外观角色调用。对于子系统而言,外观类只是另一个客户。
来个小李子:给一个文件加密 ,三个步骤 ,读源文件,保存文件,加密文件。
首先来子系统对象,需要做的就是它需要满足单一职责原则。其次,主要就是子系统的操作了 。
FileReader:文件读取类,用来读取源文件,使用StringBuffer来完成因为字符串的不变性,所以需要用StringBuffer来解决。
package facedePattern;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/**
*
* Title: FileReader
* Description:文件读取类,充当子系统
* @author HAND_WEILI
* @date 2018年9月5日
*/
public class FileReader {
public String read(String fileName) {
System.out.println("读取文件,获取明文");
StringBuffer sb = new StringBuffer();
//读取文件
try {
FileInputStream inFS = new FileInputStream(fileName);
int data;
while((data=inFS.read())!=-1) {
sb=sb.append((char)data);
}
inFS.close();
System.out.println(sb.toString());
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return sb.toString();
}
}
CipherMachine:加密类,就是将字符都取模7。模拟一下。
package facedePattern;
/**
*
* Title: CipherMachine
* Description:加密系统,模仿一下哦 。将对应的字符取模
* @author HAND_WEILI
* @date 2018年9月5日
*/
public class CipherMachine {
public String encrypt(String plainText) {
System.out.println("数据加密,将明文转换为密文");
String es = "";
for(int i=0;i
FileWrite:文件写入类,用来保存密文。
package facedePattern;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileWrite {
public void write(String encryptStr,String fileName) {
System.out.println("保存密文,写入文件");
try {
FileOutputStream outFs= new FileOutputStream(fileName);
outFs.write(encryptStr.getBytes());
outFs.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
EncryptFacade:外观类,核心类。进行调用。省去自己调用的麻烦事。
package facedePattern;
/**
*
* Title: EncryptFacade
* Description: 外观者类
* @author HAND_WEILI
* @date 2018年9月5日
*/
public class EncryptFacade {
//对子系统的引用
private FileReader fileReader;
private CipherMachine cipherMachine;
private FileWrite fileWrite;
public EncryptFacade() {
fileReader = new FileReader();
cipherMachine = new CipherMachine();
fileWrite = new FileWrite();
}
//调用子系统对象的业务方法》
public void fileEncrypt(String fileName,String fileNameDes) {
String plainStr = fileReader.read(fileName);
String encryptStr = cipherMachine.encrypt(plainStr);
fileWrite.write(encryptStr, fileNameDes);
}
}
Client:客户类,通过外观类,得到我需要的。我就是要将一个没有加密的文件,读取以后进行加密然后保存
package facedePattern;
public class Client {
public static void main(String[] args) {
EncryptFacade ef = new EncryptFacade();
ef.fileEncrypt("src//facedePattern//test.txt","src//facedePattern//test_facade.txt" );
}
}
优点:
缺点:
使用场景:
1、当客户端需要调用一系列复杂子系统时候,可以提供一个简单入口的时候使用外观模式。
2、客户端与子系统有很大的耦合性,使用外观模式可以充分解耦。
3、再层次化结构中可以使用外观模式的定义系统中每一层的入口,层与层之间不直接产生联系,而通过外观类建立联系,减低层与层之间的耦合。
我总感觉,外观模式,代理模式,适配器模式,感觉都差不多!都是干中介的事情,但是好像有些许的区别,看来理解还是不够深刻。果然需要多复习,并且多思考,最重要的就是要做几个实例然后去思考。