狀態模式-State-訂單狀態

JAVA設計模式-狀態模式-State-訂單狀態

21. State(狀態)
 
clip_image021
 
意圖:
容許一個對象在其內部狀態改變時改變它的行爲。對象看起來彷佛修改了它的類。
解釋:
好比說對訂單的提交,第一次提交是成功的,可是第二次提交的時候就會是失敗的,由於其內部狀態已經改變,而外部都是「訂單」調用了「提交」方法,同一個行爲,可是實質上形成的效果已經不一樣。
 
適用性:
一個對象的行爲取決於它的狀態, 而且它必須在運行時刻根據狀態改變它的行爲。
一個操做中含有龐大的多分支的條件語句,且這些分支依賴於該對象的狀態。這個狀態一般用一個或多個枚舉常量表示。一般, 有多個操做包含這一相同的條件結構。State模式將每個條件分支放入一個獨立的類中。這使得你能夠根據對象自身的狀況將對象的狀態做爲一個對象,這一對象能夠不依賴於其餘對象而獨立變化。

解釋:java

行爲取決於它的狀態,便是說由狀態決定行爲,方法放在狀態類中,而狀態控制亦在狀態類中進行,譬如一個按鈕,按一次是開,按一次是關,同一個行爲,可是因爲其狀態的改變,而致使不一樣的結果。
一個操做中含有龐大的多分支的條件語句,且這些分支依賴於該對象的狀態。這個狀態一般用一個或多個枚舉常量表示。一般, 有多個操做包含這一相同的條件結構。State模式將每個條件分支放入一個獨立的類中。這使得你能夠根據對象自身的狀況將對象的狀態做爲一個對象,這一對象能夠不依賴於其餘對象而獨立變化。
便是說之前你須要在某個行爲的方法裏面用if/else或者switch中寫的一堆業務,如今能夠轉移到狀態類中了,而該狀態類是獨立的,很是便於流程管理。譬如以前的開關,你須要在toggle()中寫if/else,而且須要返回flag以便判斷狀態,而使用狀態類,將狀態分爲開/關兩種狀態,只須要在狀態類的toggle()方法中寫入邏輯,將行爲後的狀態返回便可。
 
實現:
須要實現這個邏輯:
那麼咱們就須要
3個具體狀態類(已預訂,已確認,已鎖定)
以及3個行爲(確認,修改,支付)
 
抽象狀態類
[java]  view plain  copy
 
  1. abstract class OrderState {  
  2.     abstract void confirm(OrderContext orderContext);  
  3.   
  4.     abstract void modify(OrderContext orderContext);  
  5.   
  6.     abstract void pay(OrderContext orderContext);  
  7. }  

具體狀態類
[java]  view plain  copy
 
  1. class OrderedState extends OrderState {  
  2.     @Override  
  3.     void confirm(OrderContext orderContext) {  
  4.         System.out.println("訂單已確認");  
  5.         orderContext.setState(new ConfirmedState());  
  6.     }  
  7.   
  8.     @Override  
  9.     void modify(OrderContext orderContext) {  
  10.         System.out.println("訂單已修改");  
  11.         orderContext.setState(this);  
  12.     }  
  13.   
  14.     @Override  
  15.     void pay(OrderContext orderContext) {  
  16.         System.out.println("預約狀態沒法完成訂單!");  
  17.     }  
  18. }  
  19.   
  20. class ConfirmedState extends OrderState {  
  21.     @Override  
  22.     void confirm(OrderContext orderContext) {  
  23.         System.out.println("訂單已確認,請勿重複確認");  
  24.     }  
  25.   
  26.     @Override  
  27.     void modify(OrderContext orderContext) {  
  28.         System.out.println("訂單已修改,請再次確認");  
  29.         orderContext.setState(new OrderedState());  
  30.     }  
  31.   
  32.     @Override  
  33.     void pay(OrderContext orderContext) {  
  34.         System.out.println("訂單已支付,沒法再修改");  
  35.         orderContext.setState(new LockedState());  
  36.     }  
  37. }  
  38.   
  39. class LockedState extends OrderState {  
  40.     @Override  
  41.     void confirm(OrderContext orderContext) {  
  42.         System.out.println("訂單已鎖定");  
  43.     }  
  44.   
  45.     @Override  
  46.     void modify(OrderContext orderContext) {  
  47.         System.out.println("訂單已鎖定");  
  48.     }  
  49.   
  50.     @Override  
  51.     void pay(OrderContext orderContext) {  
  52.         System.out.println("訂單已鎖定");  
  53.     }  
  54. }  

背景類
[java]  view plain  copy
 
  1. class OrderContext {  
  2.     OrderState state = null;  
  3.     //新建訂單設爲已預約狀態  
  4.     OrderContext() {  
  5.         this.state = new OrderedState();  
  6.     }  
  7.   
  8.     void setState(OrderState state) {  
  9.         this.state = state;  
  10.     }  
  11.   
  12.     public void confirm() {  
  13.         state.confirm(this);  
  14.     }  
  15.   
  16.     public void modify() {  
  17.         state.modify(this);  
  18.     }  
  19.   
  20.     public void pay() {  
  21.         state.pay(this);  
  22.     }  
  23. }  
測試:
[java]  view plain  copy
 
  1. public static void main(String[] args) {  
  2.     OrderContext orderContext = new OrderContext();  
  3.     orderContext.confirm();     //已預約狀態>已確認狀態  
  4.     orderContext.modify();      //已確認狀態>已預約狀態  
  5.     orderContext.confirm();    //已預約狀態>已確認狀態  
  6.     orderContext.pay();       //已確認狀態>已鎖定狀態  
  7.     orderContext.modify();    //已鎖定狀態  
  8. }  


[java]  view plain  copy
 
  1. 訂單已確認  
  2. 訂單已修改,請再次確認  
  3. 訂單已確認  
  4. 訂單已支付,沒法再修改  
  5. 訂單已鎖定  
相關文章
相關標籤/搜索