Java設(shè)計模式之-外觀模式
什么是外觀模式?
外觀模式是一種結(jié)構(gòu)型設(shè)計模式,它提供了一個統(tǒng)一的接口,用于訪問子系統(tǒng)中的一組接口。外觀模式通過創(chuàng)建一個高層接口,簡化了復(fù)雜子系統(tǒng)的使用,并將客戶端與子系統(tǒng)的實現(xiàn)細(xì)節(jié)解耦。
主要解決什么問題?
外觀模式主要解決以下兩個問題:
簡化接口:當(dāng)存在復(fù)雜的子系統(tǒng)時,客戶端需要與多個子系統(tǒng)進(jìn)行交互,導(dǎo)致接口調(diào)用繁瑣。外觀模式提供了一個簡化的接口,將多個子系統(tǒng)的功能封裝在一個高層接口中,使客戶端的使用更加方便。
解耦客戶端與子系統(tǒng):客戶端通常需要了解子系統(tǒng)的實現(xiàn)細(xì)節(jié),與多個子系統(tǒng)的接口進(jìn)行交互,導(dǎo)致與子系統(tǒng)之間的耦合。外觀模式通過提供一個統(tǒng)一的接口,將客戶端與子系統(tǒng)的實現(xiàn)細(xì)節(jié)解耦,使得客戶端只需要與外觀對象進(jìn)行交互。
在什么時候我們需要使用外觀模式?
當(dāng)滿足以下條件時,考慮使用外觀模式:
存在復(fù)雜的子系統(tǒng),其中包含多個接口和交互過程。
希望簡化客戶端與子系統(tǒng)之間的交互,提供一個統(tǒng)一的接口。
需要解耦客戶端與子系統(tǒng)的實現(xiàn)細(xì)節(jié),減少耦合度。
用一個生活中的應(yīng)用實例來舉例、類比
假設(shè)您需要使用計算機來觀看電影。在觀影過程中,您需要打開電源、啟動計算機、打開播放器軟件、調(diào)整音量等等。這些步驟涉及到多個子系統(tǒng)和接口的調(diào)用。在這個場景中,計算機可以看作是一個外觀對象,它提供了一個簡化的接口,讓您只需按下一個按鈕即可完成所有必要的操作,而無需了解各個子系統(tǒng)的實現(xiàn)細(xì)節(jié)。
優(yōu)點
外觀模式具有以下優(yōu)點:
簡化客戶端使用:外觀模式提供了一個簡化的接口,使得客戶端使用起來更加方便。
解耦客戶端與子系統(tǒng):外觀模式將客戶端與子系統(tǒng)的實現(xiàn)細(xì)節(jié)解耦,使得客戶端只需要與外觀對象進(jìn)行交互,減少了耦合度。
提高可維護性:由于外觀模式將子系統(tǒng)封裝在一個外觀對象中,當(dāng)子系統(tǒng)發(fā)生變化時,只需修改外觀對象而不影響客戶端代碼。
缺點
外觀模式的缺點包括:
不符合開閉原則:當(dāng)需要新增或修改子系統(tǒng)的功能時,可能需要修改外觀對象的代碼。
可能引入不必要的依賴:外觀對象可能需要引入多個子系統(tǒng)對象,導(dǎo)致外觀對象與子系統(tǒng)之間產(chǎn)生依賴關(guān)系。
使用場景
外觀模式適用于以下情況:
當(dāng)存在復(fù)雜的子系統(tǒng),需要將其功能封裝在一個簡化接口中時。
當(dāng)希望解耦客戶端與子系統(tǒng)的實現(xiàn)細(xì)節(jié),降低耦合度時。
當(dāng)需要提供一個統(tǒng)一的接口,簡化客戶端的使用時。
下面是一個簡單的Java代碼示例:
// 子系統(tǒng)A
class SubsystemA {
? ? public void operationA() {
? ? ? ? System.out.println("SubsystemA operation");
? ? }
}
// 子系統(tǒng)B
class SubsystemB {
? ? public void operationB() {
? ? ? ? System.out.println("SubsystemB operation");
? ? }
}
// 外觀類
class Facade {
? ? private SubsystemA subsystemA;
? ? private SubsystemB subsystemB;
? ? public Facade() {
? ? ? ? subsystemA = new SubsystemA();
? ? ? ? subsystemB = new SubsystemB();
? ? }
? ? public void operation() {
? ? ? ? subsystemA.operationA();
? ? ? ? subsystemB.operationB();
? ? }
}
// 客戶端
public class Main {
? ? public static void main(String[] args) {
? ? ? ? Facade facade = new Facade();
? ? ? ? facade.operation();
? ? }
}
在上面的示例中,SubsystemA和SubsystemB是兩個子系統(tǒng),它們分別提供了operationA()和operationB()方法。Facade類是外觀類,封裝了對子系統(tǒng)的調(diào)用,并提供了一個簡化的接口operation()??蛻舳送ㄟ^調(diào)用外觀類的operation()方法來使用子系統(tǒng),而無需直接與子系統(tǒng)進(jìn)行交互。