設計模式-外觀模式

煮詩君發表於2020-09-01

定義

為子系統中的一組介面提供一個一致的介面,外觀模式定義了一個高層介面,這個介面使得這一子系統更加容易使用。

為了方便理解,我們可以看看下圖,左邊是未使用外觀模式時,外部客戶端直接呼叫企業中的各個子系統,呼叫鏈複雜且混亂,增大了客戶端的使用難度,右邊使用外觀模式後,客戶端直接跟外觀系統互動,而不必再依賴內部子系統了,從客戶端角度來看,呼叫變得簡單了;而從企業系統內部來看,維護也變得容易了。

實際上,外觀模式跟代理模式類似,也更偏向於架構模式,常見於企業應用整合中,企業應用整合包括介面整合,業務流程整合(過程整合),控制整合(應用整合,API整合),資料整合四個層面,而外觀模式與業務流程整合(過程整合)密切相關,因為外觀模式有業務流程優化的意味在裡面,因此,外觀模式有時也叫過程模式,例如淘寶網站首頁就可以看成是一個外觀模式的應用,因為它是多個系統的整合,並對外提供了一個一致的介面(不要死板的理解為API介面)。

UML類圖

我們再來看一下外觀模式的類圖,其實,在該模式中,與其說是類圖,不如說是架構圖,因為從定義上也可以看出,外觀模式面向的是各子系統,而非類與物件。因此,該模式也不必過於拘泥於程式碼實現,而應該更多的關注於它的設計思想,以及如何運用。

目的

  1. 為一個複雜的模組或子系統提供一個一致的外界訪問介面,降低客戶端訪問子系統的複雜度。
  2. 使客戶端與子系統之間解耦,讓子系統內部模組更易維護和擴充套件。
  3. 進行訪問控制,提高系統安全性。
  4. 維護大型遺留系統,小型系統沒必要用外觀,用代理就可以了。

和代理模式之間的異同

相同點

  • 都可以在不改變子系統程式碼的基礎上,對子系統加以控制;
  • 原有系統之間都是可以直接訪問的,兩個模式都是為了讓子系統更加容易使用;
  • 都不應該在其中新增子系統沒有的功能。

不同點

  • 外觀模式面向的是多個不同的子系統,而代理模式通常面向的是一個(或者多個相同的)子系統,例如,一個代理不能即負責代購又負責租房,但是外觀卻可以一條龍服務。
  • 外觀模式更多強調是對多個子系統的整合,而代理模式更多強調的是對某個子系統的代理,如果沒有業務整合,外觀也僅僅是個代理而已。

極端情況下,假如外觀模式中的子系統只有一個,就跟代理模式差不多了,這有點像抽象工廠模式和工廠方法模式之間的關係。

思考

首先, DDD中的Service層是外觀模式,因為它封裝了下層的Repository,讓上層更容易使用,同時上層也可以直接訪問Repository層。那麼,MVC中的Controller層,三層架構中的BLL層,微服務中的閘道器是不是外觀模式呢?

  1. Controller不算外觀模式,因為Controller雖然封裝了Service層,但Service層本身不能被使用者(Controller的上層)直接訪問,因此不是外觀,反而更像介面卡;
  2. BLL層也不算外觀模式,雖然從程式碼上看,他跟DDD中的Service層非常相似,甚至完全一樣,但三層架構是橫向切分,而DDD是縱向切分,他們從設計思想上有本質的區別。在三層架構中,雖然上層也可以直接訪問到DAL層,但這種操作在設計上是不被允許的;
  3. 閘道器中用到了外觀模式,閘道器比較複雜,其中大量用到了外觀模式,但不等於外觀模式,因為有時候閘道器也僅僅是個代理,並未做業務整合。

當然,在具體開發過程中,沒必要過分拘泥於這些細節,因為滿不滿足外觀模式的定義相對於好的設計而言,是即非充分也非必要條件,但是多思考一些細節卻可以讓自己想的更通透,何樂而不為呢?

原始碼連結

相關文章