根據單一權責原則,軟件中將一個系統劃分爲若干個子系統有利於下降整個系統的複雜性,使客戶類與子系統之間的通訊和相互依賴關係達到最小,方法之一就是引入一個外觀角色,爲子系統的訪問提供一個簡單而單一的入口。外觀模式經過引入一個新的外觀角色來下降原有系統的複雜度,同時下降客戶類與子系統類的耦合度。java
(這裏的子系統是廣義的概念,能夠是一個類,一個功能模塊,系統的一個組成部分或者一個完整的系統)編程
若是沒有外觀角色,每一個客戶端可能須要和多個子系統之間進行復雜的交互,系統的耦合度很大,簡化示意圖以下:設計模式
而引入外觀角色後,客戶端只需直接與外觀角色交互,客戶端與子系統之間的原有複雜度由外觀角色實現,從而下降系統耦合度,簡化示意圖以下:微信
外觀模式要求一個子系統的外部與其內部的通訊經過一個統一的外觀角色進行,外觀角色將客戶端與子系統的內部複雜性分隔開,使得客戶端只須要與外觀角色打交道,而不須要與子系統內部的不少對象打交道。ide
外觀模式:外部與一個子系統的通訊經過一個統一的外觀角色進行,爲子系統中的一組接口提供一個一致的入口。學習
外觀模式定義了一個高層接口,這個接口使得這一子系統更加容易使用。測試
外觀模式又叫門面模式,是一種對象結構型模式。加密
一般實現以下:設計
class Facade { private SubSystemA subSystemA = new SubSystemA(); private SubSystemB subSystemB = new SubSystemB(); private SubSystemC subSystemC = new SubSystemC(); public void method() { subSystemA.method(); subSystemB.method(); subSystemC.method(); } } class SubSystemA { public void method() { System.out.println("子系統A"); } } class SubSystemB { public void method() { System.out.println("子系統B"); } } class SubSystemC { public void method() { System.out.println("子系統C"); } }
使用外觀模式的緣由就是簡化客戶端的調用,在這裏只需定義外觀對象並調用業務方法便可:code
Facade facade = new Facade(); facade.method();
設計一個文件加密系統,加密流程包括三部分:讀取文件,加密文件,保存文件。這三個操做相對獨立,而且封裝在三個不一樣的類中,使用外觀模式設計該系統。
設計以下:
FileReader
+Encrypt
+FileWriter
Facade
FileReader
:文件讀取類Encrypt
:文件加密類FileWriter
:文件保存類代碼以下:
public class Test { public static void main(String[] args) { Facade facade = new Facade(); facade.fileEncrypt("111"); } } class FileReader { public void read(String name) { System.out.println("讀取文件"+name); } } class Encrypt { public void encrypt(String name) { System.out.println("加密文件"+name); } } class FileWriter { public void write(String name) { System.out.println("保存文件"+name); } } class Facade { private FileReader reader = new FileReader(); private Encrypt encrypt = new Encrypt(); private FileWriter writer = new FileWriter(); public void fileEncrypt(String name) { reader.read(name); encrypt.encrypt(name); writer.write(name); } }
這裏的例子比較簡單,其實就是將讀取,加密以及保存操做用外觀角色包裝起來,方便客戶端調用。
在標準的外觀模式結構中,若是須要增長,刪除或修改外觀類交互的子系統類,必須修改外觀類或客戶端的源代碼,這將違背開閉原則,好比上面的例子中須要更換一種加密方法,也就是換一個加密類,這樣須要直接修改外觀類。
能夠經過引入抽象外觀類來解決該問題,引入後,客戶端能夠針對抽象外觀類進行編程,對於新的業務需求不須要修改原有的外
觀類,只須要新增一個對應的具體外觀類便可。
首先定義抽象外觀類,接着具體外觀類繼承或者實線抽象外觀類便可。客戶端針對抽象外觀類進行編程,在運行時再肯定具體的外觀類,好比在上面例子的基礎上修改加密方法,首先定義抽象外觀類(這裏是接口,只有一個加密方法):
interface AbstractFacade { void encrypt(String name); }
接着定義具體外觀類:
class Facade1 implements AbstractFacade { private FileReader reader = new FileReader(); private Encrypt1 encrypt1 = new Encrypt1(); private FileWriter writer = new FileWriter(); @Override public void encrypt(String name) { reader.read(name); encrypt1.encrypt(name); writer.write(name); } } class Facade2 implements AbstractFacade { private FileReader reader = new FileReader(); private Encrypt2 encrypt2 = new Encrypt2(); private FileWriter writer = new FileWriter(); @Override public void encrypt(String name) { reader.read(name); encrypt2.encrypt(name); writer.write(name); } }
這兩個類除了加密方法不同其餘都同樣,測試:
AbstractFacade facade = new Facade1(); facade.encrypt("111"); facade = new Facade2(); facade.encrypt("222");
引入抽象外觀類後,客戶端針對抽象外觀類進行編程,運行時肯定具體外觀類,輸出以下:
若是以爲文章好看,歡迎點贊。
同時歡迎關注微信公衆號:氷泠之路。