大家如果喜歡高質(zhì)量的 Python 文章,可以在掘金找我:掘金個(gè)人主頁
設(shè)計(jì)模式(Design Pattern)是一套被反復(fù)使用爸邢、多數(shù)人知曉的援所、經(jīng)過分類的、代碼設(shè)計(jì)經(jīng)驗(yàn)的總結(jié)笨鸡。使用設(shè)計(jì)模式的目的:為了代碼可重用性、讓代碼更容易被他人理解、保證代碼可靠性敌土。設(shè)計(jì)模式使代碼編寫真正工程化;設(shè)計(jì)模式是軟件工程的基石脈絡(luò)运翼,如同大廈的結(jié)構(gòu)一樣返干。
通常被有經(jīng)驗(yàn)的面向?qū)ο蟮能浖_發(fā)人員所采用。設(shè)計(jì)模式是軟件開發(fā)人員在軟件開發(fā)過程中面臨的一般問題的解決方案血淌。這些解決方案是眾多軟件開發(fā)人員經(jīng)過相當(dāng)長的一段時(shí)間的試驗(yàn)和錯(cuò)誤總結(jié)出來的矩欠。
設(shè)計(jì)模式有很多中,但可以把它們歸為三類:
- 創(chuàng)建型設(shè)計(jì)模式
- 結(jié)構(gòu)型設(shè)計(jì)模式
- 行為型設(shè)計(jì)模式
而 “門面模式” (也稱外觀模式)也是眾多設(shè)計(jì)模式的一種悠夯,它屬于結(jié)構(gòu)型設(shè)計(jì)模式癌淮。
什么是門面模式(Facade)?
為子系統(tǒng)中的一組接口提供一個(gè)一致的界面
Facade 模式定義了一個(gè)高層接口沦补,這個(gè)接口使得這子系統(tǒng)更加容易使用乳蓄。
什么時(shí)候需要使用門面模式?
在以下情況下可以考慮使用外觀模式:
(1)設(shè)計(jì)初期階段策彤,應(yīng)該有意識(shí)的將不同層分離栓袖,層與層之間建立外觀模式。
(2) 開發(fā)階段店诗,子系統(tǒng)越來越復(fù)雜裹刮,增加外觀模式提供一個(gè)簡單的調(diào)用接口。
(3) 維護(hù)一個(gè)大型遺留系統(tǒng)
門面模式解決了什么問題庞瘸?
(1)實(shí)現(xiàn)了子系統(tǒng)與客戶端之間的松耦合關(guān)系捧弃。
(2)客戶端屏蔽了子系統(tǒng)組件,減少了客戶端所需處理的對象數(shù)目擦囊,并使得子系統(tǒng)使用起來更加容易违霞。
這不是 S8 剛過,蹭一波 IG牛批 的熱度瞬场,我們通過英雄聯(lián)盟的角色 -- 銳雯买鸽,來理解門面模式。我是一名爬蟲工程師贯被,常用 Python 眼五,所以接下來的代碼演示部分將采用 Python 來編寫妆艘。
為什么選擇銳雯?
因?yàn)殇J雯的技能很適合講解門面模式看幼。
大家都知道 IG.theshy 的成名英雄不是劍魔而是銳雯批旺。
他在打職業(yè)之前是韓服第一銳雯,操作簡直 666诵姜。
銳雯基本操作是什么汽煮?
光速 QA 的連招順序?yàn)椋篈-Q-地板-A-Q-地板-A-Q-地板-A, 一套傷害打下來是很猛的棚唆,今天我們就以銳雯的光速 QA 作為例子暇赤,來看看設(shè)計(jì)模式中的門面模式是怎么回事。
我可以選擇其它英雄么瑟俭?
當(dāng)然可以翎卓,你可以選擇你擅長的英雄來理解門面模式,這并不影響你收割知識(shí)摆寄。
光速 QA 的過程
都聽過光速 QA失暴,但是你了解它的過程么?A Q A Q A Q A 就完事了微饥?
要是這樣逗扒,那就很簡單了,事實(shí)上英雄聯(lián)盟有施法技能前搖動(dòng)畫和后搖動(dòng)畫欠橘,就是因?yàn)檫@些動(dòng)畫影響了英雄在技能釋放時(shí)的連貫性矩肩,而光速 QA 就是利用人物移動(dòng)的操作來抵消技能的前搖和后搖動(dòng)畫。我們來看一看肃续,光速 QA 的過程是什么:
1.首先平 A 一下敵人黍檩;
2.以最快的速度接 Q 技能;
3.接著飛速點(diǎn)擊一下地板始锚;
4.最后神速的將鼠標(biāo)移動(dòng)到回你要攻擊的目標(biāo)上刽酱。
上面是光速 QA 的第一段操作,它需要你操作 4 次瞧捌,而光速 QA 總共有 3 段棵里,意味著你要將上面的操作循環(huán) 3 次,總共就是 12 次操作姐呐。
這也就是為什么殿怜,只要練成了銳雯的光速 QA ,就能夠在短時(shí)間內(nèi)打出爆發(fā)性的傷害曙砂,讓對面的上單心慌慌...
用 Python 代碼表示光速 QA
說明一下头谜,代碼是用來表示過程以及比喻技能的(杠精請繞道),介紹一下鸠澈,英雄聯(lián)盟的英雄技能按鍵分布在 Q-W-E-R 四個(gè)鍵柱告,所以游戲中大家將各個(gè)技能的名稱簡述為 Q 技能砖织、W 技能、E 技能末荐、R 技能,這里我們還需要鍵盤和鼠標(biāo)的操作新锈。
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 代碼表示鼠標(biāo)操作
class Mouse(object):
def mouse_left_click(self):
# 鼠標(biāo)左鍵
print("鼠標(biāo)左鍵點(diǎn)擊 1 次, A 攻擊")
def mouse_right_click(self):
# 鼠標(biāo)右鍵
print("鼠標(biāo)右鍵點(diǎn)擊 1 次, 點(diǎn)擊地面")
這樣就構(gòu)成了最基本的技能和鼠標(biāo)基礎(chǔ)操作甲脏。
接下來我們使用銳雯的第一段 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 操作
運(yùn)行這段代碼,我們就可以實(shí)現(xiàn)銳雯的第一段 QA 操作:
鼠標(biāo)左鍵點(diǎn)擊 1 次, A 攻擊
釋放 Q 技能
鼠標(biāo)左鍵點(diǎn)擊 1 次, A 攻擊
釋放 Q 技能
鼠標(biāo)左鍵點(diǎn)擊 1 次, A 攻擊
釋放 Q 技能
鼠標(biāo)左鍵點(diǎn)擊 1 次, A 攻擊
如果需要 3 段 QA 操作妹笆,那么就將上方的代碼復(fù)制三份块请。
光速 QA 快捷鍵與門面模式
英雄聯(lián)盟有快捷鍵的,可以讓你簡單的使出光速 QA 操作拳缠,那么這個(gè)快捷鍵我們就可以理解為 “門面模式”墩新。快捷鍵將這些操作歸納起來窟坐,你只需要設(shè)置好快捷鍵海渊,就能夠一次性使出光速 QA。門面模式 UML 圖為:
門面模式的光速 QA 代碼
將圖形轉(zhuǎn)化為實(shí)際的代碼,首先保持原來的鍵盤和鼠標(biāo)操作不變:
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):
# 鼠標(biāo)左鍵
print("鼠標(biāo)左鍵點(diǎn)擊 1 次, A 攻擊")
def mouse_right_click(self):
# 鼠標(biāo)右鍵
print("鼠標(biāo)右鍵點(diǎn)擊 1 次, 點(diǎn)擊地面")
接著通過定義一個(gè) 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
再編寫一個(gè)召喚師臣疑,讓召喚師對 Facade (可以將 Facade 理解為英雄聯(lián)盟的快捷鍵)進(jìn)行操作:
class Client(object):
def __init__(self):
print("斷劍重鑄之日 騎士歸來之時(shí)")
def combo(self):
# 技能連招
operation = Facade()
operation.quick_attack()
def moves(self):
print("走位移動(dòng)")
為了更貼近真實(shí)操作,我們還可以為召喚師增加走位功能徙菠。
至此讯沈,門面模式所需的類和代碼都編寫完了,我們來看看召喚師如何使用:
if __name__ == "__main__":
client = Client() # 召喚師
# 召喚師 釋放連招 - 調(diào)整走位 - 釋放連招 - 調(diào)整走位 - 釋放連招
client.combo()
client.moves()
client.combo()
client.moves()
client.combo()
以上就完成了 3 段 QA 操作婿奔,運(yùn)行一下代碼缺狠,看看會(huì)發(fā)生什么:
斷劍重鑄之日 騎士歸來之時(shí)
鼠標(biāo)左鍵點(diǎn)擊 1 次, A 攻擊
釋放 Q 技能
鼠標(biāo)右鍵點(diǎn)擊 1 次, 點(diǎn)擊地面
鼠標(biāo)左鍵點(diǎn)擊 1 次, A 攻擊
走位移動(dòng)
鼠標(biāo)左鍵點(diǎn)擊 1 次, A 攻擊
釋放 Q 技能
鼠標(biāo)右鍵點(diǎn)擊 1 次, 點(diǎn)擊地面
鼠標(biāo)左鍵點(diǎn)擊 1 次, A 攻擊
走位移動(dòng)
鼠標(biāo)左鍵點(diǎn)擊 1 次, A 攻擊
釋放 Q 技能
鼠標(biāo)右鍵點(diǎn)擊 1 次, 點(diǎn)擊地面
鼠標(biāo)左鍵點(diǎn)擊 1 次, A 攻擊
是不是完成了所有的連招操作,形成了光速 QA 呢(杠精請繞路)萍摊?
寫法對比
回顧一下常規(guī)寫法挤茄,有鍵盤、鼠標(biāo)记餐,召喚師釋放 1 段 QA 操作需要共 4 步驮樊,它們之間的關(guān)系如下圖所示:
那么 3 段 QA 就需要 3 組
而門面模式的寫法,則是將所需的一組復(fù)雜操作封裝起來片酝,從而為外部的召喚師提供一個(gè)舒適囚衔、簡單的操作,它由門面雕沿、客戶端(召喚師)练湿、一組系統(tǒng)(Q、A 以及鼠標(biāo)左/右鍵操作)三部分組成审轮,像下圖所繪肥哎,每一組操作包裹在 Facade 中辽俗,召喚師需要釋放連招只需要調(diào)用 1 次 Facade 即可。
用 UML 圖表示他們的關(guān)系:
關(guān)注公眾號(hào)篡诽,可以領(lǐng)取上方所用代碼及 UML 圖
你還能聯(lián)想到哪一些英雄呢崖飘?那些英雄的技能是不是也可以用設(shè)計(jì)模式來理解?
請?jiān)谖恼孪路搅粞澡九纯茨阆矚g哪個(gè)英雄多一點(diǎn)朱浴。
<center>IG 牛批、S8 冠軍牛批...!</center>