設(shè)計(jì)模式--狀態(tài)模式(State)
前幾天由于忙工作上的事情,每天加班到10點(diǎn)左右才回家,回到家就沒(méi)有再開(kāi)電腦更新東西,今天早了一些回家,開(kāi)始繼續(xù)更新東西,今天要寫(xiě)的是狀態(tài)模式,哦,對(duì)于一個(gè)沒(méi)有狀態(tài)的人來(lái)說(shuō),寫(xiě)狀態(tài)模式,不知道會(huì)寫(xiě)成什么樣子,反正是一起討論用嘛,能把我所知道的清楚表達(dá)出來(lái)已經(jīng)很心滿意足啦。在理解狀態(tài)模式的時(shí)候,我總覺(jué)得它和策略模式很像很像,有人說(shuō)它們是孿生兄弟,那我們現(xiàn)在看看狀態(tài)模式到底是一個(gè)什么樣的東西。
狀態(tài)模式是對(duì)象的一個(gè)行為模式,它允許一個(gè)對(duì)象在其內(nèi)部狀態(tài)改變的時(shí)候改變其行為,這個(gè)對(duì)象看上去就像改了了它的類一樣。
下圖是關(guān)于紅綠燈轉(zhuǎn)換的一個(gè)實(shí)現(xiàn)類圖,具體的轉(zhuǎn)換是這樣子的,在初始的情況下,設(shè)定一個(gè)燈的狀態(tài),比如是綠燈,那么燈的下一個(gè)狀態(tài)則是黃燈,緊接著是紅燈,然后再是綠燈,依次循環(huán);通過(guò)改變燈的狀態(tài),改變其行為。
下面是這個(gè)類圖的實(shí)現(xiàn)代碼:
package com.plabmedia.state;
public interface LightState {
/**
* 打印當(dāng)前的狀態(tài)
*/
public void print(Light light);}
package com.plabmedia.state;
public class RedLight implements LightState{
@Override
public void print(Light light) {
System.out.println("current state is red");
light.setState(new GreenLight());
}}
package com.plabmedia.state;
public class YellowLight implements LightState{
@Override
public void print(Light light) {
System.out.println("current state is yellow");
light.setState(new RedLight());
}}
package com.plabmedia.state;
public class GreenLight implements LightState {
@Override
public void print(Light light) {
System.out.println("current state is green");
light.setState(new YellowLight());
}}
package com.plabmedia.state;
public class Light {
private LightState state;
public LightState getState() {
return state;
}public void setState(LightState state) {
this.state = state;
}public void print(){
state.print(this);
}public Light(LightState state){
this.state = state;
}}
package com.plabmedia.state;
public class Client {
public static void main(String args[]){
Light light = new Light(new GreenLight());
light.print();
light.print();
light.print();
light.print();
light.print();
light.print();
}}
運(yùn)行結(jié)果:
current state is green
current state is yellow
current state is red
current state is green
current state is yellow
current state is red
上面是對(duì)狀態(tài)模式一個(gè)小小的實(shí)現(xiàn),這個(gè)實(shí)現(xiàn)也僅僅是認(rèn)識(shí)級(jí)的,在我們實(shí)際應(yīng)用中,如果用到狀態(tài)模式,應(yīng)該比這個(gè)要負(fù)責(zé)的多,只是基本的結(jié)構(gòu)是相似的。那我們下面針對(duì)狀態(tài)模式做一些討論。
1.在什么情況下使用狀態(tài)模式:
- 一個(gè)對(duì)象的行為依賴于它所處的狀態(tài),對(duì)象的行為必須隨著其狀態(tài)的改變而改變;
- 需要多多重條件轉(zhuǎn)移語(yǔ)句進(jìn)行演化的時(shí)候,可以把每個(gè)分支封裝成一個(gè)狀態(tài)類;現(xiàn)在寫(xiě)代碼的時(shí)候,我是不太喜歡用條件轉(zhuǎn)移語(yǔ)句,特別是最好的那個(gè)else語(yǔ)句,我覺(jué)得它承擔(dān)的東西太多了,前面不滿足的情況它都要來(lái)處理,憑什么啊。
- 誰(shuí)來(lái)定義狀態(tài)的變化:客戶端還是狀態(tài)內(nèi)部決定?這要看當(dāng)時(shí)應(yīng)用的環(huán)境,如果狀態(tài)的變化是固定的,我覺(jué)得可以再客戶端進(jìn)行設(shè)定;如果狀態(tài)的變化依賴于前一個(gè)狀態(tài),比如在工作流系統(tǒng)中,當(dāng)前狀態(tài)是依賴于前一個(gè)狀態(tài)的,這需要狀態(tài)內(nèi)部來(lái)覺(jué)得。
- 狀態(tài)對(duì)象創(chuàng)建時(shí)機(jī):需要的時(shí)候創(chuàng)建?還是事先創(chuàng)建好所有的對(duì)象,供需要的時(shí)候調(diào)用?這要分系統(tǒng)需要來(lái)決定,如果一個(gè)系統(tǒng),狀態(tài)變化的順序固定,不那么頻繁,則可以在需要的時(shí)候創(chuàng)建所需要的對(duì)象;否則,對(duì)于頻繁變化的狀態(tài),從性能上將,還是首先創(chuàng)建好各個(gè)狀態(tài)對(duì)象,供需要時(shí)調(diào)用。
- 可以把環(huán)境類傳到具體的狀態(tài)類中,狀態(tài)類在需要的時(shí)候調(diào)用環(huán)境類,比如示例中的樣子,其實(shí)在每個(gè)狀態(tài)類里面,也可以直接調(diào)用環(huán)境類的print方法,這樣看來(lái),Client只需要初始化環(huán)境類,然后就可以看到它的狀態(tài)在不停地變化。
posted on 2012-07-21 22:23 拼搏 閱讀(1040) 評(píng)論(0) 編輯 收藏