設計模式(Design Pattern)是一套被反覆使用、多數人知曉的、經過分類的、程式碼設計經驗的總結。使用設計模式的目的:為了程式碼可重用性、讓程式碼更容易被他人理解、保證程式碼可靠性。設計模式使程式碼編寫真正工程化;設計模式是軟體工程的基石脈絡,如同大廈的結構一樣。
通常被有經驗的物件導向的軟體開發人員所採用。設計模式是軟體開發人員在軟體開發過程中面臨的一般問題的解決方案。這些解決方案是眾多軟體開發人員經過相當長的一段時間的試驗和錯誤總結出來的。
設計模式有很多中,但可以把它們歸為三類:
- 建立型設計模式
- 結構型設計模式
- 行為型設計模式
而 “門面模式” (也稱外觀模式)也是眾多設計模式的一種,它屬於結構型設計模式。
什麼是門面模式(Facade)?
為子系統中的一組介面提供一個一致的介面
Facade 模式定義了一個高層介面,這個介面使得這子系統更加容易使用。什麼時候需要使用門面模式?
在以下情況下可以考慮使用外觀模式:
(1)設計初期階段,應該有意識的將不同層分離,層與層之間建立外觀模式。
(2) 開發階段,子系統越來越複雜,增加外觀模式提供一個簡單的呼叫介面。
(3) 維護一個大型遺留系統
門面模式解決了什麼問題?
(1)實現了子系統與客戶端之間的鬆耦合關係。
(2)客戶端遮蔽了子系統元件,減少了客戶端所需處理的物件數目,並使得子系統使用起來更加容易。
這不是 S8 剛過,蹭一波 IG牛批 的熱度,我們通過英雄聯盟的角色 -- 銳雯,來理解門面模式。我是一名爬蟲工程師,常用 Python ,所以接下來的程式碼演示部分將採用 Python 來編寫。
為什麼選擇銳雯?
因為銳雯的技能很適合講解門面模式。
大家都知道 IG.theshy 的成名英雄不是劍魔而是銳雯。
他在打職業之前是韓服第一銳雯,操作簡直 666。銳雯基本操作是什麼?
光速 QA 的連招順序為:A-Q-地板-A-Q-地板-A-Q-地板-A, 一套傷害打下來是很猛的,今天我們就以銳雯的光速 QA 作為例子,來看看設計模式中的門面模式是怎麼回事。
我可以選擇其它英雄麼?
當然可以,你可以選擇你擅長的英雄來理解門面模式,這並不影響你收割知識。光速 QA 的過程
都聽過光速 QA,但是你瞭解它的過程麼?A Q A Q A Q A 就完事了?要是這樣,那就很簡單了,事實上英雄聯盟有施法技能前搖動畫和後搖動畫,就是因為這些動畫影響了英雄在技能釋放時的連貫性,而光速 QA 就是利用人物移動的操作來抵消技能的前搖和後搖動畫。我們來看一看,光速 QA 的過程是什麼:
1.首先平 A 一下敵人; 2.以最快的速度接 Q 技能; 3.接著飛速點選一下地板; 4.最後神速的將滑鼠移動到回你要攻擊的目標上。
上面是光速 QA 的第一段操作,它需要你操作 4 次,而光速 QA 總共有 3 段,意味著你要將上面的操作迴圈 3 次,總共就是 12 次操作。
這也就是為什麼,只要練成了銳雯的光速 QA ,就能夠在短時間內打出爆發性的傷害,讓對面的上單心慌慌...用 Python 程式碼表示光速 QA
說明一下,程式碼是用來表示過程以及比喻技能的(槓精請繞道),介紹一下,英雄聯盟的英雄技能按鍵分佈在 Q-W-E-R 四個鍵,所以遊戲中大家將各個技能的名稱簡述為 Q 技能、W 技能、E 技能、R 技能,這裡我們還需要鍵盤和滑鼠的操作。
Python 程式碼表示鍵盤技能
class KeyBoard(object):
""" 鍵盤 """
def keyboard_q(self):
# Q 技能
print("釋放 Q 技能")
def keyboard_w(self):
# W 技能
print("釋放 W 技能")
def keyboard_e(self):
# E 技能
print("釋放 E 技能")
def keyboard_r(self):
# R 技能
print("釋放 R 技能")
複製程式碼
Python 程式碼表示滑鼠操作
class Mouse(object):
def mouse_left_click(self):
# 滑鼠左鍵
print("滑鼠左鍵點選 1 次, A 攻擊")
def mouse_right_click(self):
# 滑鼠右鍵
print("滑鼠右鍵點選 1 次, 點選地面")
複製程式碼
這樣就構成了最基本的技能和滑鼠基礎操作。
接下來我們使用銳雯的第一段 QA 操作:
if __name__ == "__main__":
keyboard = KeyBoard()
mouse = Mouse()
# 接下來開始使用光速 QA 操作的第一輪: A-> Q-> 地板-> A
mouse.mouse_left_click() # A
keyboard.keyboard_q() # Q
mouse.mouse_right_click() # 地板
mouse.mouse_left_click() # A
複製程式碼
第一段 QA 操作
執行這段程式碼,我們就可以實現銳雯的第一段 QA 操作:
滑鼠左鍵點選 1 次, A 攻擊
釋放 Q 技能
滑鼠左鍵點選 1 次, A 攻擊
釋放 Q 技能
滑鼠左鍵點選 1 次, A 攻擊
釋放 Q 技能
滑鼠左鍵點選 1 次, A 攻擊
複製程式碼
如果需要 3 段 QA 操作,那麼就將上方的程式碼複製三份。
光速 QA 快捷鍵與門面模式
英雄聯盟有快捷鍵的,可以讓你簡單的使出光速 QA 操作,那麼這個快捷鍵我們就可以理解為 “門面模式”。快捷鍵將這些操作歸納起來,你只需要設定好快捷鍵,就能夠一次性使出光速 QA。門面模式 UML 圖為:
門面模式的光速 QA 程式碼
將圖形轉化為實際的程式碼,首先保持原來的鍵盤和滑鼠操作不變:
class KeyBoard(object):
""" 鍵盤 """
def keyboard_q(self):
# Q 技能
print("釋放 Q 技能")
def keyboard_w(self):
# W 技能
print("釋放 W 技能")
def keyboard_e(self):
# E 技能
print("釋放 E 技能")
def keyboard_r(self):
# R 技能
print("釋放 R 技能")
class Mouse(object):
def mouse_left_click(self):
# 滑鼠左鍵
print("滑鼠左鍵點選 1 次, A 攻擊")
def mouse_right_click(self):
# 滑鼠右鍵
print("滑鼠右鍵點選 1 次, 點選地面")
複製程式碼
接著通過定義一個 Facade 類,將原來的鍵鼠操作組成一套連招:
class Facade(object):
""" 門面模式 """
def __init__(self):
self.keyboard = KeyBoard()
self.mouse = Mouse()
def quick_attack(self):
# 快速攻擊
self.mouse.mouse_left_click() # A
self.keyboard.keyboard_q() # Q
self.mouse.mouse_right_click() # 地板
self.mouse.mouse_left_click() # A
複製程式碼
再編寫一個召喚師,讓召喚師對 Facade (可以將 Facade 理解為英雄聯盟的快捷鍵)進行操作:
class Client(object):
def __init__(self):
print("斷劍重鑄之日 騎士歸來之時")
def combo(self):
# 技能連招
operation = Facade()
operation.quick_attack()
def moves(self):
print("走位移動")
複製程式碼
為了更貼近真實操作,我們還可以為召喚師增加走位功能。
至此,門面模式所需的類和程式碼都編寫完了,我們來看看召喚師如何使用:
if __name__ == "__main__":
client = Client() # 召喚師
# 召喚師 釋放連招 - 調整走位 - 釋放連招 - 調整走位 - 釋放連招
client.combo()
client.moves()
client.combo()
client.moves()
client.combo()
複製程式碼
以上就完成了 3 段 QA 操作,執行一下程式碼,看看會發生什麼:
斷劍重鑄之日 騎士歸來之時
滑鼠左鍵點選 1 次, A 攻擊
釋放 Q 技能
滑鼠右鍵點選 1 次, 點選地面
滑鼠左鍵點選 1 次, A 攻擊
走位移動
滑鼠左鍵點選 1 次, A 攻擊
釋放 Q 技能
滑鼠右鍵點選 1 次, 點選地面
滑鼠左鍵點選 1 次, A 攻擊
走位移動
滑鼠左鍵點選 1 次, A 攻擊
釋放 Q 技能
滑鼠右鍵點選 1 次, 點選地面
滑鼠左鍵點選 1 次, A 攻擊
複製程式碼
是不是完成了所有的連招操作,形成了光速 QA 呢(槓精請繞路)?
寫法對比
回顧一下常規寫法,有鍵盤、滑鼠,召喚師釋放 1 段 QA 操作需要共 4 步,它們之間的關係如下圖所示:
那麼 3 段 QA 就需要 3 組
而門面模式的寫法,則是將所需的一組複雜操作封裝起來,從而為外部的召喚師提供一個舒適、簡單的操作,它由門面、客戶端(召喚師)、一組系統(Q、A 以及滑鼠左/右鍵操作)三部分組成,像下圖所繪,每一組操作包裹在 Facade 中,召喚師需要釋放連招只需要呼叫 1 次 Facade 即可。
用 UML 圖表示他們的關係:
關注公眾號,可以領取上方所用程式碼及 UML 圖你還能聯想到哪一些英雄呢?那些英雄的技能是不是也可以用設計模式來理解?
請在文章下方留言,看看你喜歡哪個英雄多一點。