電話

    0411-39943997

仟億科技
客服中心
  • 電話
  • 電話咨詢:0411-39943997
  • 手機
  • 手機咨詢:15840979770
    手機咨詢:13889672791
網絡營銷 >更多
您現在的位置:首頁 > 新聞中心 > 常見問題

設計模式中的狀態模式的一個小改進

作者:billionnet 發布于:2012/5/6 20:14:17 點擊量:

 

設計模式中的狀態模式

 

這是標準的狀態模式.其中Context管理所有狀態,而每個狀態都是自己的類,而狀態的流轉邏輯由狀態自己執行.

然后完整的狀態模式實現太過”重”,而且狀態流轉的描述在代碼上也不會是一目了然.所以我對狀態模式進行了簡化和優化.使其很”輕”,易于使用和實現,而且對于狀態流轉在代碼上也能一目了然.所有的流轉邏輯都能在一屏上顯示出來.

先來介紹一下重新優化后的狀態模式的一些概念:

  • State:首先就是狀態
  • Event:事件,事件的觸發使State狀態發生改變
  • Next:實為路徑,就是描述一個狀態 觸發某個事件后會變成具體其他狀態的描述
  • Status:狀態實例,State只是狀態的描述,而Status就狀態的實例,可以被執行根據State的描述來轉換成新的State

代碼可以見 https://github.com/zephyrleaves/easy-state

我們來看一個例子就能知道他是怎么用的了

首先我們先定義Event事件.

1
2
3
4
5
6
7
8
9
10
public enum OrderEvent implements Event{//正在進行中

 

DO,

//做完了

DONE;

@Override public String getName() {

return name();

}

}

可以看到Event實際是一個枚舉,列舉了一系列狀態相關的事件

然后我們再定義狀態

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public enum OrderState implements State {@Next(arc = {“DO->END”, “DONE->END”})

 

INIT,

@Next()

TEST,

END;

@Override public int getValue() {

return ordinal();

}

@Override public String getOrginName() {

return name();

}

@Override public OrderState getStateByName(String name) {

return valueOf(name);

}

}

可以看到State本身也是枚舉,而不同的是在狀態上有@Next這樣的annotation來描述狀態流轉的邏輯

例如INIT上的@Next 表示當前如果發生DO這個Event,那么當前狀態就是跳轉到END上

最后看一下串聯起來的執行結果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public class StatusTest {@org.testng.annotations.BeforeTest

 

public void setUp() {

}

@Test

public void testConstuructor() {

Status status = new Status(OrderState.INIT);    //初始化狀態為INIT

Assert.assertEquals(OrderState.valueOf(“INIT”), status.getCurrentState());

}

@Test

public void testHappen() {

Status status = new Status(OrderState.INIT);    //初始化狀態為INIT

Assert.assertEquals(OrderState.INIT, status.getCurrentState());

HappenedResult result = status.happen(OrderEvent.DO);      //當前狀態出發了DO事件

Assert.assertEquals(result, HappenedResult.SUCCESS);       //跳轉成功

Assert.assertTrue(result.isSuccess());

Assert.assertEquals(status.getCurrentState(), OrderState.END);    //當前狀態已經跳轉為END

Assert.assertEquals(status.getPreviousState(), OrderState.INIT);  //上一個狀態為INIT

HappenedResult result1 = status.happen(null);               //沒有發生事件

Assert.assertEquals(result1, HappenedResult.NO_EVENT);       //提示你沒事件發生

Assert.assertEquals(status.getCurrentState(), OrderState.END);         //當前狀態還是END

Assert.assertEquals(status.getPreviousState(), OrderState.INIT);       //上一個狀態還是INIT

HappenedResult result2 = status.happen(OrderEvent.DONE);      //在當前狀態發了DONE事件

Assert.assertEquals(result2, HappenedResult.NO_NEXT);         //這個狀態下沒有定義會觸發DONE事件

Assert.assertEquals(status.getCurrentState(), OrderState.END);      //當前狀態還是END

Assert.assertEquals(status.getPreviousState(), OrderState.INIT);   //上一個狀態還是INIT

Status status1 = new Status(OrderState.TEST); //初始化狀態為TEST

HappenedResult result3 = status1.happen(OrderEvent.DO);             //在當前狀態發了DO事件

Assert.assertEquals(result3, HappenedResult.NO_ARC);                //這個狀態下沒有定義會觸發的事件

Assert.assertEquals(status1.getCurrentState(), OrderState.TEST);         //當前狀態還是TEST

Assert.assertEquals(status1.getPreviousState(), null);              //沒有上一個狀態

}

}

 



分享到:


Copyright@ 2011-2016 版權所有:大連千億科技有限公司 遼ICP備11013762-3號   google網站地圖   百度網站地圖   網站地圖

公司地址:大連市沙河口區中山路692號辰熙星海國際2317 客服電話:0411-39943997 QQ:2088827823 37482752

法律聲明:未經許可,任何模仿本站模板、轉載本站內容等行為者,本站保留追究其法律責任的權利! 隱私權政策聲明

www精品一区二区三区四区