前言
今天Carson來(lái)全面總結(jié)最常用的設(shè)計(jì)模式 - 外觀模式。

其他設(shè)計(jì)模式介紹
這是一份全面 & 詳細(xì)的設(shè)計(jì)模式學(xué)習(xí)指南
Carson帶你學(xué)設(shè)計(jì)模式:?jiǎn)卫J剑⊿ingleton)
Carson帶你學(xué)設(shè)計(jì)模式:簡(jiǎn)單工廠模式(SimpleFactoryPattern)
Carson帶你學(xué)設(shè)計(jì)模式:工廠方法模式(Factory Method)
Carson帶你學(xué)設(shè)計(jì)模式:抽象工廠模式(Abstract Factory)
Carson帶你學(xué)設(shè)計(jì)模式:策略模式(Strategy Pattern)
Carson帶你學(xué)設(shè)計(jì)模式:適配器模式(Adapter Pattern)
Carson帶你學(xué)設(shè)計(jì)模式:靜態(tài)代理模式(Proxy Pattern)
Carson帶你學(xué)設(shè)計(jì)模式:動(dòng)態(tài)代理模式(Proxy Pattern)
Carson帶你學(xué)設(shè)計(jì)模式:模板方法模式(Template Method)
Carson帶你學(xué)設(shè)計(jì)模式:建造者模式(Builder Pattern)
Carson帶你學(xué)設(shè)計(jì)模式:外觀模式(Facade Pattern)
Carson帶你學(xué)設(shè)計(jì)模式:觀察者模式(Observer)
目錄

1. 介紹
1.1 定義
定義了一個(gè)高層、統(tǒng)一的接口,外部與通過(guò)這個(gè)統(tǒng)一的接口對(duì)子系統(tǒng)中的一群接口進(jìn)行訪問(wèn)。
通過(guò)創(chuàng)建一個(gè)統(tǒng)一的外觀類,用來(lái)包裝子系統(tǒng)中一個(gè) / 多個(gè)復(fù)雜的類,客戶端可通過(guò)調(diào)用外觀類的方法來(lái)調(diào)用內(nèi)部子系統(tǒng)中所有方法
如下圖:

給個(gè)網(wǎng)站的導(dǎo)航例子你就懂了:以前我需要在搜索欄逐個(gè)搜索網(wǎng)站地址;有了網(wǎng)站導(dǎo)航(用了外觀模式)后,就方便很多了

1.2 主要作用
- 實(shí)現(xiàn)客戶類與子系統(tǒng)類的松耦合
- 降低原有系統(tǒng)的復(fù)雜度
- 提高了客戶端使用的便捷性,使得客戶端無(wú)須關(guān)心子系統(tǒng)的工作細(xì)節(jié),通過(guò)外觀角色即可調(diào)用相關(guān)功能。
- 引入外觀角色之后,用戶只需要與外觀角色交互;
- 用戶與子系統(tǒng)之間的復(fù)雜邏輯關(guān)系由外觀角色來(lái)實(shí)現(xiàn)
1.3 解決的問(wèn)題
- 避免了系統(tǒng)與系統(tǒng)之間的高耦合度
- 使得復(fù)雜的子系統(tǒng)用法變得簡(jiǎn)單
2. 模式原理
2.1 UML類圖 & 組成

2.2 實(shí)例講解
接下來(lái)我用一個(gè)實(shí)例來(lái)對(duì)建造者模式進(jìn)行更深一步的介紹。
a. 實(shí)例概況
- 背景:小成的爺爺已經(jīng)80歲了,一個(gè)人在家生活:每次都需要打開(kāi)燈、打開(kāi)電視、打開(kāi)空調(diào);睡覺(jué)時(shí)關(guān)閉燈、關(guān)閉電視、關(guān)閉空調(diào);
- 沖突:行動(dòng)不方便,走過(guò)去關(guān)閉那么多電器很麻煩,代碼如下:
1.電器類:
//燈類
public class SubSystemA_Light {
public void on(){
System.out.println("打開(kāi)了燈....");
}
public void off(){
System.out.println("關(guān)閉了燈....");
}
}
//電視類
public class SubSystemB_Television {
public void on(){
System.out.println("打開(kāi)了電視....");
}
public void off(){
System.out.println("關(guān)閉了電視....");
}
}
//空調(diào)類
public class SubSystemC_Aircondition {
public void on(){
System.out.println("打開(kāi)了電視....");
}
public void off(){
System.out.println("關(guān)閉了電視....");
}
}
- 客戶端調(diào)用:小成爺爺使用電器情況
public class Facade Pattern{
public static void main(String[] args){
{
SubSystemA_Light light = new SubSystemA_Light();
SubSystemB_Television television = new SubSystemB_Television();
SubSystemC_Aircondition aircondition = new SubSystemC_Aircondition();
//起床后開(kāi)電器
System.out.prinln("起床了");
light.on();
television.on();
aircondition.on();
System.out.prinln("可以看電視了");
//睡覺(jué)時(shí)關(guān)電器
System.out.prinln("睡覺(jué)了");
light.off();
television.off();
aircondition.off();
System.out.prinln("可以睡覺(jué)了");
}
}
結(jié)果
起床了
打開(kāi)了燈
打開(kāi)了電視
打開(kāi)了空調(diào)
可以看電視了
睡覺(jué)了
關(guān)閉了燈
關(guān)閉了電視
關(guān)閉了空調(diào)
可以睡覺(jué)了
從上面可以看出,在不使用外觀模式的情況下,小成爺爺需要對(duì)每個(gè)電器都進(jìn)行操作,非常不方便
客戶端與三個(gè)子系統(tǒng)都發(fā)生了耦合,使得客戶端程序依賴與子系統(tǒng)
解決方案
小成買了一個(gè)智能家具控制器(外觀對(duì)象/統(tǒng)一接口)給他爺爺,他爺爺只需要一鍵就能打開(kāi)/關(guān)閉 燈、電視機(jī)、空調(diào)
- 即用外觀模式來(lái)為所有子系統(tǒng)設(shè)計(jì)一個(gè)統(tǒng)一的接口
- 客戶端只需要調(diào)用外觀類中的方法就可以了,簡(jiǎn)化了客戶端的操作
1.電器類同上
- 外觀類:智能遙控器
public class Facade{
SubSystemA_Light light;
SubSystemB_Television television ;
SubSystemC_Aircondition aircondition;
//傳參
public Facade(SubSystemA_Light light,SubSystemB_Television television,SubSystemC_Aircondition aircondition){
this.light = light;
this.television = television ;
this.aircondition =aircondition;
}
//起床后一鍵開(kāi)電器
public void on{
System.out.prinln("起床了");
light.on();
television.on();
aircondition.on();
}
//睡覺(jué)時(shí)一鍵關(guān)電器
System.out.prinln("睡覺(jué)了");
light.off();
television.off();
aircondition.off();
}
}
- 客戶端調(diào)用:爺爺使用智能遙控器的時(shí)候
public class Facade Pattern{
public static void main(String[] args){
{
//實(shí)例化電器類
SubSystemA_Light light = new SubSystemA_Light();
SubSystemB_Television television = new SubSystemB_Television();
SubSystemC_Aircondition aircondition = new SubSystemC_Aircondition();
//傳參
Facade facade = new Facade(light,television,aircondition);
//客戶端直接與外觀對(duì)象進(jìn)行交互
facade.on;
System.out.prinln("可以看電視了");
facade.off;
System.out.prinln("可以睡覺(jué)了");
結(jié)果
起床了
打開(kāi)了燈
打開(kāi)了電視
打開(kāi)了空調(diào)
可以看電視了
睡覺(jué)了
關(guān)閉了燈
關(guān)閉了電視
關(guān)閉了空調(diào)
可以睡覺(jué)了
通過(guò)上述這個(gè)常見(jiàn)的生活例子,我相信你已經(jīng)完全明白了外觀模式的原理了??!
3. 優(yōu)缺點(diǎn)
在全面解析完后,我來(lái)分析下其優(yōu)缺點(diǎn):
3.1 優(yōu)點(diǎn)
- 降低了客戶類與子系統(tǒng)類的耦合度,實(shí)現(xiàn)了子系統(tǒng)與客戶之間的松耦合關(guān)系
- 只是提供了一個(gè)訪問(wèn)子系統(tǒng)的統(tǒng)一入口,并不影響用戶直接使用子系統(tǒng)類
- 減少了與子系統(tǒng)的關(guān)聯(lián)對(duì)象,實(shí)現(xiàn)了子系統(tǒng)與客戶之間
的松耦合關(guān)系,松耦合使得子系統(tǒng)的組件變化不會(huì)影響到它的客戶。
- 外觀模式對(duì)客戶屏蔽了子系統(tǒng)組件,從而簡(jiǎn)化了接口,減少了客戶處理的對(duì)象數(shù)目并使子系統(tǒng)的使用更加簡(jiǎn)單。
- 引入外觀角色之后,用戶只需要與外觀角色交互;
- 用戶與子系統(tǒng)之間的復(fù)雜邏輯關(guān)系由外觀角色來(lái)實(shí)現(xiàn)
- 降低原有系統(tǒng)的復(fù)雜度和系統(tǒng)中的編譯依賴性,并簡(jiǎn)化了系統(tǒng)在不同平臺(tái)之間的移植過(guò)程
因?yàn)榫幾g一個(gè)子系統(tǒng)一般不需要編譯所有其他的子系統(tǒng)。一個(gè)子系統(tǒng)的修改對(duì)其他子系統(tǒng)沒(méi)有任何影響,而且子系統(tǒng)內(nèi)部變化也不會(huì)影響到外觀對(duì)象。
3.2 缺點(diǎn)
- 在不引入抽象外觀類的情況下,增加新的子系統(tǒng)可能需要修改外觀類或客戶端的源代碼,違背了“開(kāi)閉原則”
- 不能很好地限制客戶使用子系統(tǒng)類,如果對(duì)客戶訪問(wèn)子系統(tǒng)類做太多的限制則減少了可變性和靈活性。
4. 應(yīng)用場(chǎng)景
- 要為一個(gè)復(fù)雜的子系統(tǒng)對(duì)外提供一個(gè)簡(jiǎn)單的接口
- 提供子系統(tǒng)的獨(dú)立性
- 客戶程序與多個(gè)子系統(tǒng)之間存在很大的依賴性
引入外觀類將子系統(tǒng)與客戶以及其他子系統(tǒng)解耦,可以提高子系統(tǒng)的獨(dú)立性和可移植性。
- 在層次化結(jié)構(gòu)中,可以使用外觀模式定義系統(tǒng)中每一層的入口
層與層之間不直接產(chǎn)生聯(lián)系,而通過(guò)外觀類建立聯(lián)系,降低層之間的耦合度。
5. 與適配器模式的區(qū)別
- 外觀模式的實(shí)現(xiàn)核心主要是——由外觀類去保存各個(gè)子系統(tǒng)的引用,實(shí)現(xiàn)由一個(gè)統(tǒng)一的外觀類去包裝多個(gè)子系統(tǒng)類,然而客戶端只需要引用這個(gè)外觀類,然后由外觀類來(lái)調(diào)用各個(gè)子系統(tǒng)中的方法。
- 這樣的實(shí)現(xiàn)方式非常類似適配器模式,然而外觀模式與適配器模式不同的是:適配器模式是將一個(gè)對(duì)象包裝起來(lái)以改變其接口,而外觀是將一群對(duì)象 ”包裝“起來(lái)以簡(jiǎn)化其接口。它們的意圖是不一樣的,適配器是將接口轉(zhuǎn)換為不同接口,而外觀模式是提供一個(gè)統(tǒng)一的接口來(lái)簡(jiǎn)化接口。
6. 總結(jié)
- 本文主要對(duì)外觀模式進(jìn)行了全面介紹
- 接下來(lái)我會(huì)對(duì)每種設(shè)計(jì)模式進(jìn)行詳細(xì)的分析,歡迎關(guān)注Carson_Ho的簡(jiǎn)書(shū),不定期分享關(guān)于安卓開(kāi)發(fā)的干貨,追求短、平、快,但卻不缺深度。

請(qǐng)點(diǎn)贊!因?yàn)槟愕墓膭?lì)是我寫(xiě)作的最大動(dòng)力!
相關(guān)文章閱讀
這是一份全面 & 詳細(xì)的設(shè)計(jì)模式學(xué)習(xí)指南
Carson帶你學(xué)設(shè)計(jì)模式:?jiǎn)卫J剑⊿ingleton)
Carson帶你學(xué)設(shè)計(jì)模式:簡(jiǎn)單工廠模式(SimpleFactoryPattern)
Carson帶你學(xué)設(shè)計(jì)模式:工廠方法模式(Factory Method)
Carson帶你學(xué)設(shè)計(jì)模式:抽象工廠模式(Abstract Factory)
Carson帶你學(xué)設(shè)計(jì)模式:策略模式(Strategy Pattern)
Carson帶你學(xué)設(shè)計(jì)模式:適配器模式(Adapter Pattern)
Carson帶你學(xué)設(shè)計(jì)模式:靜態(tài)代理模式(Proxy Pattern)
Carson帶你學(xué)設(shè)計(jì)模式:動(dòng)態(tài)代理模式(Proxy Pattern)
Carson帶你學(xué)設(shè)計(jì)模式:模板方法模式(Template Method)
Carson帶你學(xué)設(shè)計(jì)模式:建造者模式(Builder Pattern)
Carson帶你學(xué)設(shè)計(jì)模式:外觀模式(Facade Pattern)
Carson帶你學(xué)設(shè)計(jì)模式:觀察者模式(Observer)