【Python設計模式】04 門面模式-與門面相適
四、門面模式-與門面相適 Python3.x
本章研究結構型設計模式:門面模式
本章主題
- 結構型設計模式概要
- 利用UML圖理解門面設計模式
- Python3.x實現程式碼的真實用例
- 門面模式與最少知識原則
1. 理解結構型設計模式
- 結構型模式描述如何將物件和類組合成更大的結構
- 結構型模式是一種能夠簡化設計工作的模式,因為它能夠找出更加簡單的方法來認識或表示實體之間的關係。在面向物件世界中,實體指的是物件或類
- 類模式可以通過繼承來描述抽象,從而提供更有用的程式介面,而物件模式則描述瞭如何將物件聯絡起來從而組成更大的物件。結構型模式是類和物件模式的綜合體
2. 理解門面設計模式
門面模式:經過建築表面,可以欣賞建築的面貌,卻無需瞭解建築內部結構的複雜性
門面在隱藏內部系統複雜性的同時,為客戶端提供了一個介面,以便它們可以輕鬆地訪問系統
- 門面模式為子系統中的一組介面提供一個統一的介面,並定義一個高階介面來幫助客戶端通過簡單的方式使用子系統
- 門面所解決問題是,如何用單個介面物件來表示複雜的子系統。實際上,它並不是封裝子系統,而是對底層子系統進行組合
- 它促進了實現與多個客戶端的解耦
3. UML 類圖
我們可以藉助UML 類圖來深入探討門面模式
門面模式主要有3個參與者:
- 門面:門面的主要責任是將一組複雜的系統封裝起來,從而為外界提供一個舒適的外觀
- 系統:這代表一組不同的子系統,使整個系統混雜在一起,難以觀察或使用。
- 客戶端:客戶端與門面進行互動,這樣就可以輕鬆地與子系統進行通訊並完成工作了。不必擔心繫統的複雜性
3.1 門面
- 它是一個介面,它知道某個請求可以交由哪個子系統進行處理
- 它使用組合將客戶端的請求委派給相應的子系統物件
3.2 系統
- 它實現子系統的功能,同時,系統由一個類表示。理想情況下,系統應該由一組負責不同的任務的類來表示
- 它處理門面物件分配的工作,但並不知道門面,而且不引用它
3.3 客戶端
- 客戶端是例項化門面的類
- 為了讓子系統完成相應的工作,客戶端需要向門面提出請求
4. Python實現門面模式
應用場景:假設你需要舉行一場婚禮,並且由你來張羅一切
門面模式的角度分析:
- 客戶端:你需要在婚禮前及時完成所有的準備工作。每一項安排都應該頂級的
- 門面:會務經理負責與所有相關人員進行交涉,這些人員負責處理食物、花卉裝飾等
- 子系統:它們代表提供餐飲、酒店管理和花卉裝飾等服務的系統
# coding: utf-8
# 門面類
class EventManager(object):
def __init__(self):
print("Event Manger:Let me talk to folks\n")
def arrage(self):
self.hotelier = Hotelier() # 酒店類
self.hotelier.bookHotel() # 預定酒店
self.florist = Florist() # 鮮花類
self.florist.setFlowerRequirements() # 指定哪種花來裝飾婚禮
self.caterer = Caterer() # 宴席承辦人
self.caterer.setCuisine() # 指定酒店的飯菜型別
self.musician = Musician() # 婚禮音樂類
self.musician.setMusicType() # 音樂要求
class Hotelier(object):
def __init__(self):
print("Arranging the Hotel for Marriage ---")
def __isAvailable(self):
print("Is the Hotel free for the event on given day? ")
return True
def bookHotel(self):
if self.__isAvailable:
print("Registed the Booking\n\n")
class Florist(object):
def __init__(self):
print("Flower Descrations for the Event ---")
def setFlowerRequirements(self):
print("choose Roses, Carnations and Lilies that day\n\n")
class Caterer(object):
def __init__(self):
print("Food Arrangments for the Event ---")
def setCuisine(self):
print("Chinese & Continental Cuisine to be serverd\n\n")
class Musician(object):
def __init(self):
print("Musicial Arrangments for the Merriage --")
def setMusicType(self):
print("Jazz & Classcial will be played\n\n")
class You(object):
def __init__(self):
print("You:: Whoa! Marriage Arrangements ??!!")
def askEventManager(self):
print("You:: Let's Contact the Event Manager\n\n")
em = EventManager()
em.arrage()
def __del__(self):
print("You:: Thanks to Event Manager, all preparations done!")
you = You()
you.askEventManager()
執行結果:
You:: Whoa! Marriage Arrangements ??!!
You:: Let’s Contact the Event Manager
Event Manger:Let me talk to folks
Arranging the Hotel for Marriage —
Registed the Booking
Flower Descrations for the Event —
choose Roses, Carnations and Lilies that day
Food Arrangments for the Event —
Chinese & Continental Cuisine to be serverd
Jazz & Classcial will be played
You:: Thanks to Event Manager, all preparations done!
我們通過以下方式將門面模式與真實世界場景相關聯
- EventManager 類是簡化介面的門面
- EventManager 通過組合建立子系統的物件,如 Hotelier, Caterer,等等
5. 最少知識原則
門面模式背後的設計原理就是最少知識原則
最少知識原則:指導我們減少物件之間的互動
- 在設計系統時,對於建立的每個物件,都應該考察與之互動的類的數量,以及互動的方式
- 遵循這個原則,就能夠避免建立許多彼此緊密耦合的類的情況
- 如果類之間存在大量的依賴關係,那麼系統就會變得難以維護。如果對系統中的任務一部分進行修改,都可能導致系統的其他部分被無意改變,這意味著系統會退化,是應該堅決避免的
6. 常見問答
- 迪米特法則是什麼,它與門面模式有何關聯?
迪米特法則是一個設計準則
- 每個單元對系統中的其他單元知道的越少越好
- 單位應該只與其朋友交流
- 單元不應該知道它操作的物件的內部細節
最少知識原則和迪米特法則是一致的,都是指向鬆耦合理論。
-
子系統可以有多個門面嗎?
是的,可以一組子系統元件實現多個門面 -
最少知識原則的缺點是什麼?
門面提供了一個簡化的介面供客戶端與子系統互動。本著提供簡化介面的精神,應用可能會建立多個不必要的介面,這增加了系統的負責性並且降低了執行時的效能 -
客戶端可以獨立訪問子系統嗎?
是的,實際上,由於門面模式提供了簡化的介面,這使得客戶端不必擔心繫統的複雜性 -
門面是否可以新增自己的功能?
門面可以將其“想法”新增到子系統中,例如確保子系統的改進順序由門面來決定
7. 小結
- 結構型設計模式簡介
- 門面的基礎知識,以及如何將其高效地應用於軟體架構中
- 如何利用門面模式建立一個簡單的介面來供客戶使用
- 由於門面並沒有對子系統進行封裝,因此即使不通過門面,客戶端也可以自由訪問子系統
- UML 類圖,Python3.x實現門面模式的示例程式碼
- 最少知識原則,以及該原則是如何指導門面設計模式的
- 常見問題解答