變化多端的狀態模式 State Pattern

2021-09-02 02:54:03 字數 3168 閱讀 6428

現在寫字樓越建越高,碼農上個班不但要擠個地鐵,還要擠個電梯。電梯的執行簡單有這麼幾個狀態:執行、停止、關閉、開啟,電梯想要正常的執行,就必須得遵循一定的規則,例如執行的時候不能開門,開門狀態不能執行。按照平常的邏輯,分別建立open,close,run,stop四個方法,方法裡通過switch當前的狀態,執行不同的動作。這種處理有幾個問題:

1、擴充套件性太差

如果電梯還有兩個狀態:通電狀態和斷電狀態。那就要在open,close,run,stop四個方法裡都要增加判斷條件,這與開閉原則相違背。

2、非常規狀態無法實現

電梯在門開著的狀態下就不能上下執行了嗎?電梯有沒有發生過只有執行沒有停止狀態呢?電梯故障嘛。還有電梯在檢修的時候,可以在stop狀態下不開門,這也是正常的業務需求啊。如果加上這些需求,又有多少程式要改動?

既然平常的辦法會帶來這麼多問題,當然要找好的模式來解決——狀態模式

實現類圖如下:

在類圖中,定義了乙個liststate抽象類,宣告了乙個受保護的型別content變數,這個是串聯各個狀態的封裝類。封裝的目的很明顯,就是電梯物件內部狀態的變化不被呼叫類知曉,也就是迪公尺特法則了,並且還定義了四個具體的實現類,承擔的是狀態的產生以及狀態間的轉換過渡。具體實現**:

<?php 

abstract class liftstate

public abstract function open();

public abstract function close();

public abstract function run();

public abstract function stop();

}class openningstate extends liftstate

public function open()

public function run() {}

public function stop() {}

}class closingstate extends liftstate

public function open()

public function run()

public function stop()

}class runningstate extends liftstate

public function open() {}

public function run()

public function stop()

}class stoppingstate extends liftstate

public function open()

public function run()

public function stop()

}class content

public function getliftstate()

public function setliftstate( liftstate $liftstate )

public function open()

public function close()

public function run()

public function stop()

}$content = new content();

$content->setliftstate( new closingstate() );

$content->open();

$content->close();

$content->run();

$content->stop();

$content->close();

?>

執行結果:

電梯門開啟

電梯門關閉

電梯開動了

電梯停止了

[finished in 0.1s]

狀態模式的定義當乙個物件內在狀態改變時允許其改變行為,這個物件看起來像改變了其類。狀態模式的核心是封裝,狀態的變更引起了行為的變更,從外部看起來就好像這個物件對應的類發生了改變一樣。看看狀態模式的三個角色:

1、state——抽象狀態角色

介面或抽象類,負責物件狀態定義,並且封裝環境角色以實現狀態切換

2、concretestate——具體狀態角色

每乙個具體狀態必須完成兩個職責:本狀態的行為管理以及趨向狀態處理,通俗地說,就是本狀態下要做的事情,以及本狀態如何過渡到其他狀態

3、content——環境角色

定義客戶端需要的介面,並且負責具體狀態的切換

狀態模式相對比較複雜,它提供了一種對物質運動的另乙個觀察視角,通過狀態變更促使行為的變化,就類似水的狀態變更一樣,一碗水的初始狀態是液態,通過加熱轉變為氣態,狀態的改變同時也引起體積的擴大,然後就產生了乙個新的行為。

狀態模式的優點

1、結構清晰

避免了過多的swith...case或if...else語句的使用,避免了程式的複雜性,提高系統的可維護性

2、遵循設計原則

很好地體現了開閉原則和單一職責原則,每乙個狀態都是乙個子類,你要增加狀態就增加子類,你要修改狀態,你只修改乙個子類就可以了。

3、封裝性非常好

這也是狀態模式的基本要求,狀態變換放置到類的內部來實現,外部的呼叫不用知道類內部如何實現狀態和行為的變換。

狀態模式的缺點

子類會太多,也就是類膨脹,不好管理。

狀態模式的使用場景

1、行為隨狀態改變而改變的場景

這也是狀態模式的根本出發點,例如許可權設計,人員的狀態不同即使執行相同的行為結果也會不同,在這種情況下需要考慮使用狀態模式

2、條件、分支判斷語句的替代者

在程式中大量使用switch語句或者if判斷語句會導致程式結構不清晰,邏輯混亂,使用狀態模式可以很好地避免這一問題,它通過擴充套件子類實現了條件的判斷處理

狀態模式的注意事項

狀態模式適用於當某個物件在它的狀態發生改變時,它的行為也隨著發生比較大的變化,也就是說在行為受狀態約束的情況下可以使用狀態模式,而且使用時物件的狀態最好不要超過5個。

讓手機成為變化多端的電子產品

首屆google暑期大學生部落格分享大賽 2010 andriod篇 現在手機功能越來越強大了,強大到幾乎可以替換掉很多以前手中的電子產品,像 mp4啦等等,好多。不過仍然很多人還是回去單獨的購買的這些電子產品,即使是手機中有這樣的功能並且相比較來說效能啊,功能啊也不比這些產品差。其實回想平時的使用...

設計模式(十八) 狀態變化模式 memento

狀態變化模式包括 state和memento 備忘錄 在元件構建過程中,某些物件的狀態經常面臨變化,如何對這些變化進行有效的管理,又同事維持高層模組的穩定?軟體構建過程中,某些物件狀態轉換過程中,如果想回溯到之前的狀態,又不想暴露實現細節。乙個程式有在每個時候擁有的序列號都是不同的,代表他這個時候的...

狀態模式 打工人一天的狀態變化

狀態模式 state 定義 當乙個物件的內在狀態改變時,允許改變其行為,這個物件看起來像是改變了其類。什麼是狀態 應用程式中的部分物件可能會根據不同的情況做出不同的行為,我們把這種物件稱為有狀態的物件,而把影響物件行為的乙個或多個動態變化的屬性稱為狀態 優點 缺點 模式的結構 背景 打工人從早到晚打...