首頁 >Java >java教程 >Java設計模式-外觀模式

Java設計模式-外觀模式

黄舟
黄舟原創
2017-02-06 11:44:211656瀏覽

概述

今天要說的外觀模式是一個相對簡單的設計模式,而且在日常的開發中,可能你也會時常使用它,只是你可能並未想過這是一個設計模式。本文會從一些實例著手,來對本文要說明的外觀模式進行盡可能全面的講解。希望你有益。

引言

這裡插入一條引言的目的是讓你回想一下,在你日常開發中何時用到了外觀模式。 

可能你的 boss 會這樣安排你一個任務。這可能是個核心模組,模組會有它的一個功能,只是你的 boss 可能只想要你提供一個給他呼叫的介面。他會這麼跟你說:嗨,小明,我們現在的這個系統裡需要一個核心的功能 P0,它就交給你實現吧。你只要給我可以呼叫的介面就好了,你程式碼的內部邏輯我不需要知道的。去做吧。 

如果你時常被安排這樣的任務,我想你應該已經掌握外觀模式了。

定義

外觀模式提供了一個統一的接口,用來存取子系統中的一群接口。外觀模式定義一個高層接口,讓子系統更容易使用。

非外觀模式

這裡我就使用《大話設計模式》書中的例子了,感覺這個例子還是挺形象的。現在假設你是個股民(只是博主不炒股,也不知道這裡會不會有說得不對的地方,如果有你就當沒看見吧。。^_^),你想做一些理財活動。你看中了兩支股票、一支國債和一支房地產。

如果讓你現在來寫這份程式碼,你的程式碼框架可能會像下面的這幅類別圖:

Java設計模式-外觀模式

這裡只列舉了股票的程式碼,是因為其他理財活動的邏輯與股票的邏輯是一致的。冗餘的程式碼除了佔地方之外並沒有再多的好處了。 

StockA.java

public class StockA {
    private int stockCount = 0;
    public void sell(int count){
        stockCount -= count;
        System.out.println("卖了" + count + "支 A 股票");
    }

    public void buy(int count){
        stockCount += count;
        System.out.println("买了" + count + "支 A 股票");
    }
    public int getStockCount() {
        return stockCount;
    }
}

下面的程式碼是處理理財者的,對於一個簡單地買進買下邏輯,理財者都要花費這麼多的程式碼處理,實在是折磨人嘛。 

Investors.java

public class Investors {

    public static void main(String[] args) {
        StockA stockA = new StockA();
        StockB stockB = new StockB();
        NationalDebt debt = new NationalDebt();
        RealEstate estate = new RealEstate();

        stockA.buy(100);
        stockB.buy(200);
        debt.buy(150);
        estate.buy(120);

        stockA.sell(100);
        stockB.sell(200);
        debt.sell(150);
        estate.sell(120);
    }
}

上面說的這些是在沒有使用外觀模式的情況下寫的程式碼。也就是說下面要說的外觀模式可以讓程式碼更簡單明了。

外觀模式

在上面的非外觀模式中,我們看到了一些不是很友善的程式碼邏輯。而外觀模式可以基於更高層次的封裝,從而達到對呼叫者更加透明。以下是修改後的外觀模式類別圖:

Java設計模式-外觀模式

FundFacade.java

public class FundFacade {

    private StockA stockA = null;
    private StockB stockB = null;
    private NationalDebt debt = null;
    private RealEstate estate = null;

    public FundFacade() {
        stockA = new StockA();
        stockB = new StockB();
        debt = new NationalDebt();
        estate = new RealEstate();
    }

    public void buyAll(int count) {
        stockA.buy(count);
        stockB.buy(count);
        debt.buy(count);
        estate.buy(count);
    }

    public void sellAll(int count) {
        stockA.sell(count);
        stockB.sell(count);
        debt.sell(count);
        estate.sell(count);
    }

    public void buyStockA(int count) {
        stockA.buy(count);
    }

    public void sellNationalDebt(int count) {
        debt.sell(count);
    }
}

上面的程式碼則是外觀的核心類別:FundFacade。在理財系統中的所有操作都可以透過這個類別來實現。你透過這個類可以很方便地實現對股票、國債、房地產等理財項目的操作,而不用關心裡面究竟是怎麼處理的。這是對使用者來說是件好事,不是嗎?

來看看用戶的操作吧(當然上面圖類已經反映了絕大部分效果了),這是用戶的程式碼邏輯: 

Investors.java

public class Investors {

    public static void main(String[] args) {
        FundFacade facade = new FundFacade();
        facade.buyAll(120);
        facade.buyStockA(50);
        facade.sellAll(80);
    }
}

看看,用戶只要告訴FundFacade 類,買入什麼、賣出什麼、買多少、賣多少,就可以達到目的。實在是太方便了。 

看看股票 A 的代碼吧,其實它並什麼實質的變化。這也是外觀模式的魅力所在,它不用你去修改原來子系統的程式碼,只要做一件事,建立更高層次的封裝。當然,這裡我做了一些簡單地修改,StockA 的存取權限。既然要對使用者透明,那麼我的子系統就沒有必要再對使用者開放了,不是嗎?因為我們已經有專業的外交官- FundFacade。 

StockA.java

class StockA {
    private int stockCount = 0;
    void sell(int count){
        stockCount -= count;
        System.out.println("卖了" + count + "支 A 股票");
    }

    void buy(int count){
        stockCount += count;
        System.out.println("买了" + count + "支 A 股票");
    }
    int getStockCount() {
        return stockCount;
    }
}

外觀模式是一個相對簡單的設計模式,你可以輕鬆掌握並使用它。只是我想說,外觀模式也會有一定的限制。相信你已經發現了。 

由於我們把子系統所有的操作都交給了 FundFacade 類別來處理,所以我們就受到了 FundFacade 類別的約束了。例如上面的 FundFacade 類別中並沒有實現單獨對 StockB 的操作,那麼我們就不能單獨對 StockB 進行操作了,除非你在 FundFacade 類別中封裝一個對 StockB 操作的介面。

外觀模式的應用

上面的描述中我們不僅知道瞭如何使用外觀模式,也了解了外觀模式的局限,所以我們應該站在客觀的立場,有選擇性地使用它。這裡說一個我在工作中使用外觀模式的例子吧。 

目前專案的老大讓我去實現一個系統中的某一個模組,我想這應該是一個核心模組吧。這個模組的功能是,檢查一個資料夾下的所有檔案是否包含了敏感資訊。而這個模組中會有很多小的子模組(當然老大並不會關心這些子模組做的事情),例如AC 自動機的模式匹配、壓縮檔案的全自動解壓縮、各種格式檔案(doc/xls/ ppt/zip/eml/rtf/pdf 等等,絕大部分的文件格式基本上都在吧)、日誌系統等等。 

我不可能去跟老闆說,你要完成的功能是要先去幹嘛、再去幹嘛、再去幹嘛、再去幹嘛… … 

哦,天啦。煩死了,你能對它封裝一下嗎? (當然,這些只是我的心理活動。事實上,我還沒有讓老大說明我的設計過程) 

封裝過後,我只要告訴老大,去調用這個類別的這個方法就 ok 了。這樣老大那邊就不用操心裡面的邏輯了,雖然如果出了錯就是你的責任,可那也本該就 是你的責任啊。哈哈。 。 。 

好了,扯蛋就到這裡。不管是上面正兒八經地模式詳解,還是下面的胡說八道,我都希望它可以讓你充分了解本文這個設計模式,學習並合理使用它。

以上就是Java設計模式-外觀模式的內容,更多相關內容請關注PHP中文網(www.php.cn)!


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn