搜尋
首頁Javajava教程Java設計模式-外觀模式

概述

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

引言

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

可能你的 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
為什麼Java是開發跨平台桌面應用程序的流行選擇?為什麼Java是開發跨平台桌面應用程序的流行選擇?Apr 25, 2025 am 12:23 AM

javaispopularforcross-platformdesktopapplicationsduetoits“ writeonce,runany where”哲學。 1)itusesbytiesebyTecodeThatrunsonAnyJvm-備用Platform.2)librarieslikeslikeslikeswingingandjavafxhelpcreatenative-lookingenative-lookinguisis.3)

討論可能需要在Java中編寫平台特定代碼的情況。討論可能需要在Java中編寫平台特定代碼的情況。Apr 25, 2025 am 12:22 AM

在Java中編寫平台特定代碼的原因包括訪問特定操作系統功能、與特定硬件交互和優化性能。 1)使用JNA或JNI訪問Windows註冊表;2)通過JNI與Linux特定硬件驅動程序交互;3)通過JNI使用Metal優化macOS上的遊戲性能。儘管如此,編寫平台特定代碼會影響代碼的可移植性、增加複雜性、可能帶來性能開銷和安全風險。

與平台獨立性相關的Java開發的未來趨勢是什麼?與平台獨立性相關的Java開發的未來趨勢是什麼?Apr 25, 2025 am 12:12 AM

Java將通過雲原生應用、多平台部署和跨語言互操作進一步提昇平台獨立性。 1)雲原生應用將使用GraalVM和Quarkus提升啟動速度。 2)Java將擴展到嵌入式設備、移動設備和量子計算機。 3)通過GraalVM,Java將與Python、JavaScript等語言無縫集成,增強跨語言互操作性。

Java的強鍵入如何有助於平台獨立性?Java的強鍵入如何有助於平台獨立性?Apr 25, 2025 am 12:11 AM

Java的強類型系統通過類型安全、統一的類型轉換和多態性確保了平台獨立性。 1)類型安全在編譯時進行類型檢查,避免運行時錯誤;2)統一的類型轉換規則在所有平台上一致;3)多態性和接口機制使代碼在不同平台上行為一致。

說明Java本機界面(JNI)如何損害平台獨立性。說明Java本機界面(JNI)如何損害平台獨立性。Apr 25, 2025 am 12:07 AM

JNI會破壞Java的平台獨立性。 1)JNI需要特定平台的本地庫,2)本地代碼需在目標平台編譯和鏈接,3)不同版本的操作系統或JVM可能需要不同的本地庫版本,4)本地代碼可能引入安全漏洞或導致程序崩潰。

是否有任何威脅或增強Java平台獨立性的新興技術?是否有任何威脅或增強Java平台獨立性的新興技術?Apr 24, 2025 am 12:11 AM

新興技術對Java的平台獨立性既有威脅也有增強。 1)雲計算和容器化技術如Docker增強了Java的平台獨立性,但需要優化以適應不同雲環境。 2)WebAssembly通過GraalVM編譯Java代碼,擴展了其平台獨立性,但需與其他語言競爭性能。

JVM的實現是什麼,它們都提供了相同的平台獨立性?JVM的實現是什麼,它們都提供了相同的平台獨立性?Apr 24, 2025 am 12:10 AM

不同JVM實現都能提供平台獨立性,但表現略有不同。 1.OracleHotSpot和OpenJDKJVM在平台獨立性上表現相似,但OpenJDK可能需額外配置。 2.IBMJ9JVM在特定操作系統上表現優化。 3.GraalVM支持多語言,需額外配置。 4.AzulZingJVM需特定平台調整。

平台獨立性如何降低發展成本和時間?平台獨立性如何降低發展成本和時間?Apr 24, 2025 am 12:08 AM

平台獨立性通過在多種操作系統上運行同一套代碼,降低開發成本和縮短開發時間。具體表現為:1.減少開發時間,只需維護一套代碼;2.降低維護成本,統一測試流程;3.快速迭代和團隊協作,簡化部署過程。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能