- 外觀模式:
爲子系統中的一組接口提供一個統一的入口。外觀模式定義了一個高層接口,這個接口使得子系統更加容易調用。
從外觀模式的定義中可以瞭解到,其實外觀模式相當於一箇中間人,比如說你要去酒店吃飯,你並不需要知道菜的做法,不需要知道菜的清洗過程,也不需要知道菜的來源。你只需要喊上服務員和他說我要吃什麼就可以了,這裏的服務員其實就相當於一個外觀角色,也就是一個更高層的接口。而飯店中的各種菜就相當於一個一個子系統。 - 外觀模式的示意圖:
- 外觀模式包含的角色:
外觀角色: 這是外觀角色的核心類,一般情況下,外部的客戶端可以調用這個類裏面的方法,而這個類又清楚一個或多個子類的功能,因此,他可以將外部發來的請求,傳遞給到合適的子類去執行。
子系統角色: 這個角色有一個或者多個。每個子系統既可以被外觀角色調用,又可以被外部系統調用。並不是說,有個外觀角色後子系統就不能被外部客戶端調用了,這點要注意。外部系統還是可以跳過外觀角色自己去調用子系統。 - 外觀角色示例代碼:
場景:假設去酒店吃飯,點了麻婆豆腐和紅燒肉。你只需要和服務員說你需要這兩個就可以了,不需要知道做法,清洗過程,以及菜的原料的來源
子系統類:
紅燒肉:
public class HongShaoRou {
private static HongShaoRou instance = null;
private HongShaoRou() {
}
public static HongShaoRou getInstance(){
if (instance==null){
instance = new HongShaoRou();
}
return instance;
}
public void get(){
System.out.println("去菜市場肉店店買原材料<<<<<<");
}
public void wash(){
System.out.println("清洗原材料<<<<<<");
}
public void cook(){
System.out.println("烹飪<<<<<<");
}
}
麻婆豆腐:
public class MaPoDouFu {
private static MaPoDouFu instance = null;
private MaPoDouFu() {
}
public static MaPoDouFu getInstance(){
if (instance==null){
instance=new MaPoDouFu();
}
return instance;
}
public void get(){
System.out.println("去菜市場豆腐店買原材料<<<<<<");
}
public void wash(){
System.out.println("清洗原材料<<<<<<");
}
public void cook(){
System.out.println("烹飪<<<<<<");
}
}
服務員(外觀角色):
public class Waiter {
public void order(){
HongShaoRou hongShaoRou = HongShaoRou.getInstance();
MaPoDouFu maPoDouFu = MaPoDouFu.getInstance();
maPoDouFu.get();
hongShaoRou.cook();
}
}
測試主函數:
public class Main {
public static void main(String[] args) {
Waiter waiter = new Waiter();
waiter.order();
MaPoDouFu maPoDouFu = MaPoDouFu.getInstance();
maPoDouFu.get();
}
}
從測試主函數中,可以看出,有了外觀角色並不妨礙客戶端去獨立的調用子系統。
5. 外觀模式的優缺點
優點:
- 外觀模式爲客戶端屏蔽了一部分子系統,減少了客戶端所需要處理的類的對象,這樣在一定程度上簡化了客戶端的代碼。
- 鬆耦合,將客戶端和子系統之間的耦合降到很低的程度,在這種情況下,子系統發生變化,不會影響客戶端,只需要調整外觀角色即可。
- 子系統之間相互獨立,互不影響。
缺點: - 違背了開閉原則,修改子系統可能要修改外觀類
- 外觀模式的使用場景
- 當客戶端需要調用一系列複雜子系統時候,可以提供一個簡單入口的時候使用外觀模式。
- 需要將客戶端與子系統解耦
- 在層次化結構中可以使用外觀模式定義系統中的每一層的入口,層與層之間不直接產生聯繫。而通過外觀類產生聯繫。其實也就是解耦合。