最近在學php框架Laravel,發現裏面有很多Facade,所以特地去學習了一下,發現原來是某個設計模式。所以寫下來做個筆記。
例子
那麼對應到編程之中我們寫的某一個功能可能需要調用到很多類,如果後續維護者去維護這個功能的時候也需要清楚所調用的每一個類那時間成本太高,而且也不利於維護。各個類之間的聯繫太多,我們稱之爲耦合性過高。
那麼能不能有一箇中間類就是爲了這個功能服務的,我們只需要把所需要調用的類的相關邏輯寫在這個中間類之中就可以完成該功能。
我們就拿股票和基金舉個例子,投資者可以同時買入賣出多個股票,或者投資者可以買賣基金實現對多個股票買入賣出。都可以實現對數個股票的買入賣出。
代碼
我們先來看看投資者直接買賣多個股票的情況:
public class Main {
public static void main(String[] args) {
IStock stockA=new StockA();
IStock stockB=new StockB();
IStock stockC=new StockC();
stockA.Buy();
stockB.Buy();
stockC.Buy();
stockA.Sell();
stockB.Sell();
stockC.Sell();
}
}
class StockA implements IStock{
@Override
public void Sell() {
System.out.println("sell StockA ");
}
@Override
public void Buy() {
System.out.println("buy StockA ");
}
}
class StockB implements IStock{
@Override
public void Sell() {
System.out.println("sell StockB ");
}
@Override
public void Buy() {
System.out.println("buy StockB ");
}
}
class StockC implements IStock{
@Override
public void Sell() {
System.out.println("sell StockC ");
}
@Override
public void Buy() {
System.out.println("buy StockC ");
}
}
以上代碼有三個股票類StockA,StockB,StockC,都實現了IStock接口。
可以見到如果需要買賣股票用戶需要了解這三個股票,然後逐一操作。時間成本過高,而且跟每一個股票都有聯繫耦合性過高。
那麼如果我們用一個基金Fund,把這些股票封裝起來會是怎麼樣的呢?
public class Main {
public static void main(String[] args) {
Fund1 fund1=new Fund1();
fund1.bugFund();
fund1.sellFund();
}
}
class Fund1 {
IStock stockA = new StockA();
IStock stockB = new StockB();
IStock stockC = new StockC();
public void sellFund() {
stockA.sell();
stockB.sell();
stockC.sell();
}
public void bugFund() {
stockA.buy();
stockB.buy();
stockC.buy();
}
}
class StockA implements IStock {
@Override
public void sell() {
System.out.println("sell StockA ");
}
@Override
public void buy() {
System.out.println("buy StockA ");
}
}
class StockB implements IStock {
@Override
public void sell() {
System.out.println("sell StockB ");
}
@Override
public void buy() {
System.out.println("buy StockB ");
}
}
class StockC implements IStock {
@Override
public void sell() {
System.out.println("sell StockC ");
}
@Override
public void buy() {
System.out.println("buy StockC ");
}
}
這樣只需要基金類瞭解每個股票,用戶無需瞭解每個股票就可以完成買賣。
什麼是外觀模式(門面模式)
看完例子和代碼,概括一下什麼叫外觀模式:
爲子系統中的一組接口提供一個一致的界面,此模式定義了一個高層接口,這個接口使得這一子系統更加容易使用。
上面是我自己畫的圖有點粗糙。
客戶類可以通過Facade類使用到子系統的功能,而不用直接知道每個子系統的實現,甚至不用知道幾個子系統的存在。而子系統在開發的時候不用使用Facade任何信息
與代理模式的區別
可能有些人看了覺得外觀模式結構上跟代理模式有點相似。那麼我們下面用一兩句話說說代理模式與外觀模式有什麼不一樣。
代理模式 用一個代理類代表另一個列的功能,不改變被代理類的功能。目的是控制被代理類的訪問
外觀模式 主要使用外觀類隱藏系統複雜性 爲客戶類提供更簡化的方法和對系統類方法委託調用。