這是屬於設計模式中的對象行爲模式之一
在TCPConnection中維護着一個TCPState,在不同狀態下,維護着一個不同的TCPState,例如:stablished狀態下,維護着對應TCPstablished,實現該狀態下對應的Open(),Close(),Acknowledge()。如果切換狀態,其實就是切換TCPState對象,這樣對應的Open(),Close(),Acknowladge()也就變成對應狀態下的實現了,這就是我的理解,換成官方的說法:允許一個對象在其內部狀態改變時改變它行爲。對象看起來似乎修改了它的類。
具體使用例子:
開發播放器時,往往要處理很多狀態。例如在點擊播放時,需要判斷當前內部的狀態,就會出現很if else,例如僞代碼如下
public void play(){
if(curStatus == START){
// nodo
}else if(curStatus == PAUSE){
player.play();
curStatus == START;
}else if(curStatus == PREPARE){
// 相應的提示
}
}
public void pause(){
if(curStatus == START){
player.pause();
curStatus = PAUSE;
}else if(curStatus == PAUSE){
// nodo
}else if(curStatus == PREPARE){
// 相應的提示
}
}
public void prepare(Object object){
if(curStatus == START){
player.parepare(Object obj);
// 更新某些顯示狀態
}else if(curStatus == PAUSE){
player.parepare(Object obj);
// 更新某些顯示狀態
}else if(curStatus == PREPARE){
player.parepare(Object obj);
}
curStatus = PREPARE;
}
當狀態多了,就維護不了。如果使用狀態模式
public class playerWrap{
public Player player;
public Status curStatus = new PrepareStatus();
public play(){
curStatus.play(this);
}
public pause(){
curStatus.pause(this);
}
public prepare(Object object){
curStatus.prepare(this.object);
}
}
public interface Status{
public play(Object playerWrap);
public pause(Object playerWrap);
public prepare(Object playWrap,Object obj);
}
// 準備狀態下
public class PrepareStatus{
public play(Object playerWrap){
// 相關提示
}
public pause(Object playerWrap){
// 相關提示
}
public prepare(Object playWrap,Object obj){
playWrap.player.prepare(obj);
playWrap.curStatus = new PlayStatus();
}
}
// 暫停狀態下
public void PauseStatus{
public play(Object playerWrap){
playerWrap.play();
playerWrap.curStatus = new PlayStatus();
}
public pause(Object playerWrap){
// nodo
}
public prepare(Object playWrap,Object obj){
playWrap.player.prepare(obj);
playWrap.curStatus = new PlayStatus();
}
}
// 播放狀態下
public void PlayStatus{
public play(Object playerWrap){
// nodo
}
public pause(Object playerWrap){
playerWrap.pause();
playerWrap.curStatus = new PauseStatus();
}
public prepare(Object playWrap,Object obj){
playWrap.player.prepare(obj);
playWrap.curStatus = new PlayStatus();
}
}
第一感覺就是代碼量多了很多,但是在不同狀態下的對應play(),pause(),prepare()響應的設計就變的簡單明瞭,不會因爲錯刪了if else而出現的邏輯錯誤或者少了if情況的判斷而出現的無響應情況。而且對於狀態增減在代碼改動就變得輕鬆多了。如果減少狀態,只要刪除對應的Status類,修改涉及的地方即可,或如果增加狀態,只要增加對應的Status類,並且增加相關的方法即可。