天天看點

淺談設計模式(一):狀态模式|外觀模式|代理模式

計劃開一個設計模式的系列,介紹常見的幾種設計模式,本文涉及的設計模式包含以下3種:狀态模式,外觀模式和代理模式

前言

計劃開一個設計模式的系列,介紹常見的幾種設計模式,本文涉及的設計模式包含以下3種

狀态模式:state pattern

外觀模式:facade pattern

代理模式:proxy pattern 

備注:下文适合看過《海賊王》的人閱讀,沒看過海賊王的觀衆請在父母陪同下閱讀

在狀态模式的設計方案裡,一個主類(稱為context類),可以在内部狀态變化的時候一次性改變它的「所有行為」,而這個「所有行為」會被我們聚合到不同的類(state1,state2,state3)裡面去。

這個内部狀态我們可以了解為一個可以手動設定的state變量,設定它可以讓context内部的state1切換為state2,或者是從state2切換為state3。

這麼做,相比起傳統的代碼邏輯會發生什麼變化呢?在傳統的代碼裡,我們可能會在每個方法下,都寫一大段if-else的狀态判斷邏輯裡,然後對不同狀态分别做處理,這個時候代碼非常松散,不利于閱讀和擴充,是以我們選擇以「狀态」為依據, 把這些if-else的每一部分都「聚合」到不同的狀态(不同的state類)裡面去,然後通過一個主類(context),去統一維護和管理。這樣,邏輯上就清晰了很多,也大大降低了維護和擴充的難度。 

Example

草帽路飛,是熱血漫《海賊王》的主角,像其他許多同類型的作品一樣,主角有自己不同層次戰鬥的狀态,進化過程如下所示

二檔:加速血液的流動,大幅提高速度和身體強度,代表大招是「橡膠Jet火箭炮」(拳)和 「橡膠Jet」(踢)

三檔:向橡膠的身體吹入空氣,使身體變成巨人,攻擊力大增。代表大招是「橡膠巨人火箭炮」(拳)和「橡膠巨人戰斧」(踢)

四檔:将武裝色霸氣和橡膠果實融合,攻擊和速度再次強化,代表大招是「橡膠獅子火箭炮」(拳)和「橡膠犀牛榴彈炮」(踢)

下圖描述的是主角路飛初次進化為「二檔」的曆史性時刻

我們發現,主角路飛擁有不同的戰鬥狀态:二檔,三檔,四檔,并且大招的使用是類似的,無非就是用拳頭還是用腳踢的問題,但是攻擊力和招式上都不同,我們可以根據這個狀态的統一性抽象一個state接口出來:

然後建立二檔,三檔,四檔類,并且實作state接口

最後,路飛可能會在戰鬥中随時切換狀态,比如從二檔切換到三檔,或者從三檔切換到四檔,是以我們要設定一個Context類去管理,在這個類裡面,它有兩個功能

随時切換狀态

代理調用狀态類的方法

測試

輸出

外觀模式很簡單且容易了解,但了解之後卻非常有用。

說白了就是:把不同類的不同接口,統一代理到一個類裡面對外輸出,使代碼具有良好的封裝性

咱們還是拿海賊王的一個情境舉個例子

比如說,在海賊王367裡,草帽海賊團 VS 巨人僵屍奧茲 的時候,索隆,山治,佛蘭奇,烏索普和喬巴使用了一招非常精(you)彩(zhi)的技能:合體-大皇帝。

也就是說,合體後的草帽海賊團,在能夠使用每個人的絕招的同時,是作為“大皇帝”這個整體對外暴露的

我們使用外觀模式去實作的話,代碼邏輯如下所示

首先每個成員我們用一個類去表示

然後我們用一個整體的類,去代理上面的每個成員類的邏輯

附帶一張圖,hhhh

使用一個類接管另一個類所有的方法調用,同時能在原來類的方法調用前,加入一些自己的“中間邏輯”。這種方式被稱為代理模式。

假設類B 是類A的代理類,那麼在調用類B的方法的時候,實際還是通過類B去調用類A的接口,但是現在所有的「控制權」都已經牢牢掌握在類B手裡了,代理類B能夠很自由的加入一些中間邏輯。

顯然,類B和類A起到的功能是相同的,我們可以抽象一個接口,去讓原類(A )和代理類(B)去實作

不好意思,這裡還是用我熟悉的海賊王打個比方,在七武海-多佛朗明哥剛剛出場的時候,他就用線線果實提供的能力,操控兩名海軍自相殘殺。

如果我們把海軍抽象為一個類的話,那麼多佛朗明哥就是「海軍類」的代理類了,實際上我們發現

實質出手傷人的并不是海軍,而是多佛朗明哥,也就是代理類掌握了真正的控制權

直接出手傷人的仍然是海軍,也就是代理類仍然調用的是原類的接口

代碼如下

1.我們抽象一個海軍戰士的接口出來

2.讓海軍軍官實作這個接口

3.讓多佛朗明哥也實作這個接口

End

我叫彭湖灣,請叫我胖灣

繼續閱讀