策略模式 狀態模式

2021-08-24 22:59:42 字數 2391 閱讀 4046

當設計乙個物件可能在不同情況下有不同的行為時,一般使用的是父類 子類 多型過載的方法,

person a=new whiteperson();

person b=new blackperson();

a.speak();// i'm white

b.speak();// i'm black

但這樣做不好的地方在於 假如物件建立後了之後想在執行時改變物件的行為是不可能的,(當然可以用if else判斷狀態值,但這樣

一、多次判斷狀態的話有重複**  二、增加狀態的時候增加else會違反開閉原則)除非重新建立物件,所以這時可以用策略分離行為

inte***ce speakaction(){

void speak();

class blackspeak implements speakaction(){

void speak(){

print "i'm black"

class whitespeak implements speakaction(){

void speak(){

print "i'm white"

person{

speakaction speak;

void speak(){

speak.speak();

void setspeak(speakaction speak){

this.speak=speak;

這樣當你想改變行為的時候通過setspeak設定新的行為就可以了

狀態模式的類圖和策略模式的類圖很相似,都是面向乙個介面有一系列不同的實現,然後呼叫的時候面向介面呼叫不同的實現;但是,策略模式和狀態模式雖然類圖上很相似,但是運用的時候,個人覺得有很大的區別,關鍵在於你在如何理解你的**需求和設計要求,狀態模式在gof的定義如下:

當乙個狀態的內部狀態改變時允許改變其行為,這個物件看起來改變了其類;

狀態模式主要突出了兩個字:」改變」,對!物件的狀態決定了狀態的行為,事物的本質決定了事物的行為,我們精神亢奮的時候,我們拼命的工作,我們拼命的工作就導致了我們身心疲憊,物品們身心疲憊就導致我們的行為是需要休息;從這裡我們可以看出,事物的內在狀態決定了事物所做出的行為,而事物的行為勢必又會改變我們事物的狀態,兩者在不斷的相互影響,然後實現狀態的遷移和躍遷;

從這兩點,我們可以看出策略模式和狀態模式的應用場景有很大的不同;乙個是封裝一系列平行且複雜多變的實現方式,乙個是實現把物件的內在狀態的變化封裝起來,用外部行為來表現出來;

example:

* 帳戶(account)分為普通帳戶,vip帳戶和信用卡帳戶三種.

* 每個帳戶都可以執行取錢,存錢,登出三種操作

* 關於取錢操作的細節:

普通帳戶每次取錢限額為1000元,不能透支

vip帳戶每次取錢限額為3000元,不能透支

信用卡帳戶每次取錢限額為3000元,可以透支

* 另外每個帳戶有四種可能的狀態:新建、正常、凍結、掛失

* 帳號處於不同狀態時對於上面提到的三種操作會產生影響:

新建狀態時不能執行登出操作

掛失狀態時不能執行存錢、取錢操作

凍結狀態時不能執行存錢、取錢、登出操作

這是簡單的需求,在設計時,

* 我將帳戶設定為抽象類(account),普通帳戶,vip帳戶和信用卡帳戶為其子類

* 使用狀態模式管理帳戶的四種狀態,具體做法為:建立介面accountstate,其中包含取錢,存錢,登出三個方法,然後給出四個實現類,分別對應新建、正常、凍結、掛失四種狀態。在accout中保持乙個對狀態的引用

問題:在實現狀態模式中的三個方法的時候出現了問題,以取錢為例,顯然取錢時要判斷當前帳號的類別,這樣一來難免引入if判斷,二來需要在狀態類中依賴account子類,感覺並不好,請教好的解決思路。

(為了避免**冗餘,希望能用策略模式實現取錢,存錢等方法)

>以取錢為例,顯然取錢時要判斷當前帳號的類別,這樣一來難免引入if判斷,

這個問題是因為你狀態設計有些問題,我培訓時一直強調:使用狀態模式之前一定要搞清楚事件和狀態,這個案例中,取錢是個動作,無疑是事件,目前你的狀態有新建、正常、掛失、凍結和登出四個狀態,其他都是事件,你必須將這四個狀態設為四個狀態物件,事件導致狀態變化,你要分析下這四個狀態的切換是依靠什麼事件完成的。

象取錢這樣的事件,我目前發現不能造成上述四個狀態的切換,所以,取錢應該寫在普通的業務層裡面,當然,為了封裝只有正常狀態才可以取錢這個規則,你可以在狀態模式基礎上再封裝一層規則策略層,在其中將取錢規則寫入,外部客戶端呼叫時,只需傳入事件特徵如取錢,然後獲得結果:要麼正常;要麼返回特定exception,無法取錢。

至於if else只是乙個設計結果的體現,可能會在規則策略層也用到if else,但是這時我的if else已經是乙個非常簡單,粒度很小的判斷了,這就達到設計目的了。

希望對你有幫助。

二來需要在狀態類中依賴account子類,感覺並不好,

狀態模式和策略模式

策略模式 商場 方案,可以有多種 買x返y,z折扣,積分,直降a。一次 活動可以只選擇其中的一種 策略,彼此之間沒有影響。狀態模式 乙個人一天的工作狀態 早上精神百倍,下午還好,晚上很累。早中晚各是一種狀態,但只有三種狀態聯合起來,才能完成 一天的狀態 這件事情,相當於把一天的狀態分成了三個部分了。...

狀態模式和策略模式比較

說到策略模式,我們最先想到的就是商店的收銀方式 不滿100,正常收費 超過100不滿300,超過的部分打八折 超過300,全價九折!解決這個問題最最普通的方法就是大量的if else 而它帶來的就是無情的難以維護,每次條件變更都會修改原 嚴重違反了開閉原則。顯而易見,策略模式的解決方式就是封裝了一系...

論策略模式和狀態模式

策略模式 定義了演算法家族,這些演算法可以相互替換。此模式讓演算法的變化,不會影響到使用演算法的客戶。也就是說讓客戶動態地使用演算法。設計原則 使用策略模式要掌握乙個原則 封裝變化,封裝是物件導向的乙個思維方式,我們要把變化的部分封裝,相同的部分抽象。狀態模式 當乙個物件的內在狀態改變時,允許改變其...