大話設計模式七:外觀模式
一.模式定義
物件結構型模式。外部與一個子系統的通訊必須通過一個統一的外觀物件進行,為子系統中的一組介面提供一個一致的介面,外觀模式定義了一個高層介面,這個介面使得這一子系統更加容易使用。
Facade Pattern: Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use.
二.模式要素
Facade: 外觀角色
SubSystem:子系統角色
呼叫者
三.舉例說明
最近房市有點坑,我們就來拿它舉例吧。假如你手上有三套房子,現在房價跌得太猛,心灰意冷,於是需要全部賣掉套現。你靈機一動,這還不簡單,上手就寫程式碼。後來發現好煩啊,為了賣掉三套房子,需要寫很多重複的程式碼。你就想簡化一下,外觀模式正好可以幫你大忙。
四.模式例項
工程結構如下:
1.IHouse.java 房屋介面
package Facade; /** * @program: DesignModes * @description: IHouse * @author: Lei Dong * @create: 2018-10-12 22:03 **/ public interface IHouse { /** * 賣房 */ void sell(); }
2.House1.java 房屋1
package Facade; /** * @program: DesignModes * @description: 第一套房 * @author: Lei Dong * @create: 2018-10-12 22:07 **/ public class House1 implements IHouse { private String desc = "第一套房"; @Override public void sell() { System.out.println("賣掉" + this.desc); } }
3.House2.java 房屋2
package Facade;
/**
* @program: DesignModes
* @description: 第二套房
* @author: Lei Dong
* @create: 2018-10-12 22:07
**/
public class House2 implements IHouse {
private String desc = "第二套房";
@Override
public void sell() {
System.out.println("賣掉" + this.desc);
}
}
4.House3.java 房屋3
package Facade;
/**
* @program: DesignModes
* @description: 第三套房
* @author: Lei Dong
* @create: 2018-10-12 22:07
**/
public class House3 implements IHouse {
private String desc = "第三套房";
@Override
public void sell() {
System.out.println("賣掉" + this.desc);
}
}
5.HouseFacade.java 房屋外觀類
package Facade;
/**
* @program: DesignModes
* @description: HouseFacade
* @author: Lei Dong
* @create: 2018-10-12 22:09
**/
public class HouseFacade {
private House1 house1;
private House2 house2;
private House3 house3;
public HouseFacade() {
house1 = new House1();
house2 = new House2();
house3 = new House3();
}
/**
* 賣出全部房屋
*/
public void sellHouses() {
house1.sell();
house2.sell();
house3.sell();
}
}
6.Main.java 呼叫者
package Facade;
/**
* @program: DesignModes
* @description: Main
* @author: Lei Dong
* @create: 2018-10-12 22:02
**/
public class Main {
public static void main(String[] args) {
// 不用外觀模式的寫法
System.out.println("不用外觀模式的寫法");
House1 house1 = new House1();
House2 house2 = new House2();
House3 house3 = new House3();
house1.sell();
house2.sell();
house3.sell();
System.out.println();
// 使用外觀模式的寫法
System.out.println("用外觀模式的寫法");
HouseFacade houseFacade = new HouseFacade();
houseFacade.sellHouses();
}
}
執行結果:
分析:
發現了嗎,有HouseFacade類在main函式中賣掉三套房只需要寫2行程式碼。但是沒有HouseFacade類直接寫的話需要6行程式碼,這就是最明顯的區別,加入寫SDK當然是要一兩行解決問題。
五.總結
1.外觀模式的優點
(1)對客戶遮蔽子系統元件,減少了客戶處理的物件數目並使得子系統使用起來更加容易。通過引入外觀模式,客戶程式碼將變得很簡單,與之關聯的物件也很少。
(2)實現了子系統與客戶之間的鬆耦合關係,這使得子系統的元件變化不會影響到呼叫它的客戶類,只需要調整外觀類即可。
(3)降低了大型軟體系統中的編譯依賴性,並簡化了系統在不同平臺之間的移植過程,因為編譯一個子系統一般不需要編譯所有其他的子系統。一個子系統的修改對其他子系統沒有任何影響,而且子系統內部變化也不會影響到外觀物件。
(4)只是提供了一個訪問子系統的統一入口,並不影響使用者直接使用子系統類。
2.外觀模式的缺點
(1)不能很好地限制客戶使用子系統類,如果對客戶訪問子系統類做太多的限制則減少了可變性和靈活性。
(2)在不引入抽象外觀類的情況下,增加新的子系統可能需要修改外觀類或客戶端的原始碼,違背了“開閉原則”。
3.外觀模式適用環境
(1)當要為一個複雜子系統提供一個簡單介面時可以使用外觀模式。該介面可以滿足大多數使用者的需求,而且使用者也可以越過外觀類直接訪問子系統。
(2)客戶程式與多個子系統之間存在很大的依賴性。引入外觀類將子系統與客戶以及其他子系統解耦,可以提高子系統的獨立性和可移植性。
(3)在層次化結構中,可以使用外觀模式定義系統中每一層的入口,層與層之間不直接產生聯絡,而通過外觀類建立聯絡,降低層之間的耦合度。