
定義
當(dāng)一個對象在其內(nèi)部狀態(tài)改變的時候改變其行為。這個對象看上去就像是改變了它的類一樣。又稱狀態(tài)對象模式,狀態(tài)模式是對象的行為模式。
角色
- 1.環(huán)境(Context)角色 上下文:
定義客戶端所感興趣的接口,并且保留一個具體狀態(tài)類的實例。這個定義了對象的當(dāng)前狀態(tài) - 2.抽象狀態(tài)(State)角色
定義一個接口,用以封裝環(huán)境(Context)對象的一個特定的狀態(tài)所對應(yīng)的行為。 - 3.具體狀態(tài)(ConcreteState)角色
每一個具體狀態(tài)類都實現(xiàn)了環(huán)境(Context)的一個狀態(tài)所對應(yīng)的行為。
開發(fā)中
如果一個事件在不同狀態(tài)下處理的事情不同,通常用if else 來判斷狀態(tài)在做處理,如果有很多觸發(fā)事件只是在幾個狀態(tài)中,那么就需要對每個觸發(fā)事件都做一個不同的判斷;或者在某些情況下要添加、移除一個事件,那么這樣是非常費事的。
比如說計算機的大小寫,如果讓每個按鍵都做一個判斷,那就要26次判斷;加入我們在按按鍵的時候,提前設(shè)置狀態(tài),然后再狀態(tài)抽象中去做處理,就方便得多;
簡單實現(xiàn):
(1)抽象一個狀態(tài)接口,接口中定義觸發(fā)事件的方法名
(2)創(chuàng)建不同狀態(tài)的類(大寫、小寫兩個類),都實現(xiàn)狀態(tài)接口;
(3)創(chuàng)建一個控制器,控制狀態(tài)和觸發(fā)事件;
(4)客戶端只需要去調(diào)用控制器就可以;
代碼
環(huán)境Context
public class TvContext {
private TVState tvState=new PowerOff();
public void setTate(TVState tvState)
{
this.tvState=tvState;
}
public void turnOn()
{
setTate(new PowerOn());
tvState.turnOn();
}
public void turnOff()
{
setTate(new PowerOff());
tvState.turnOff();
}
public void nextChannel()
{
tvState.nextChannel();
}
public void preChannel() {
tvState.preChannel();
}
}
抽象狀態(tài)接口
public interface TVState {
public void nextChannel();
public void preChannel();
public void turnOn();
public void turnOff();
}
具體狀態(tài)
public class PowerOff implements TVState{
@Override
public void nextChannel() {
}
@Override
public void preChannel() {
}
@Override
public void turnOn() {
System.out.println("開機");
}
@Override
public void turnOff() {
System.out.println("關(guān)機 無效");
}
}
使用場景
一個對象的行為取決于他的狀態(tài),并且他必須在運行時根據(jù)狀態(tài)改變他的行為,代碼中包含大量與對象相關(guān)的條件語句,例如一個操作中含有多分支語句。這些分支歷來與該對象狀態(tài)模式將每一個條件分支放入一個獨立類中,這使得你可以根據(jù)對象自身的情況將狀態(tài)作為一個對象。這一對象可以不依賴于其他對象而獨立變化。這樣通過過多的,重復(fù)的if-else分支語句。
需求
電視遙控器,分為開機和關(guān)機兩種狀態(tài),在開機狀態(tài)下可以通過遙控器進行頻道切換,調(diào)整音量操作,但是開機鍵是無效的。在關(guān)機狀態(tài)下 頻道切換,調(diào)整音量,關(guān)機都是無效的。只有開機鍵是有效的。
Android中應(yīng)用
1.WiFi、GPRS等狀態(tài)
2.用戶的是否登陸狀態(tài)(用戶轉(zhuǎn)發(fā)、評論、購買等都需要判斷用戶登錄狀態(tài))