狀態模式

  先簡單介紹一下狀態模式:將與狀態有關處理邏輯分散到代表對象狀態各個類中! 
狀態之間的改變都對應一個動作,一個動作可能對應多個狀態的改變(動作來描述。可能不是特別準確),如提交,審覈.... 

state模式的兩個原則: 
1.有幾個動作就有幾個方法,一個動作可能對應多個狀態轉換,這些方法都定義在同一個接口裏。 
2.有幾個狀態就有幾個實現上述接口的類。 

用戶升級vip例子:首先用戶必須是註冊用戶,普通用戶升級vip需要提交真實的個人信息,工作人員根據提交信息的真實性進行審覈。審覈通過成爲vip用戶,審覈未通過,可以再次申請。升級到vip以後,如果查到有違反紀律的。降級到普通用戶。需要重新提交vip申請。 

[img]/upload/p_w_upload/50463/5d802be4-ebcf-3bc8-8e1e-4f6c4b163c13.jpg" alt="[/img] 
先定義接口UserState 

Java代碼  收藏代碼
  1. public interface UserState {  
  2. public UserService userService = new UserService();  
  3. // 狀態爲0代表普通用戶,這些狀態主要用於持久化到數據  
  4. public final static int COMMON_STATUS = 0;  
  5. // 狀態爲1代表待審覈用戶  
  6. public final static int FOR_VERIFY_STATUS = 1;  
  7. // 狀態爲2是代表vip用戶  
  8. public final static int VIP_STATUS = 2;  
  9.   
  10. // 提交信息  
  11. public void submit() throws Exception;  
  12.   
  13. // 審覈沒通過  
  14. public void rollback() throws Exception;  
  15.   
  16. // 審覈通過  
  17. public void pass() throws Exception;  
  18.   
  19. public int getStatus();  



代表各個狀態的類 
未提交信息的用戶NotSubmitUser.java 

Java代碼  收藏代碼
  1.    
  2. public class NotSubmitUser implements UserState {  
  3.     public void pass() throws Exception {  
  4.         throw new Exception("no support method");  
  5.     }  
  6.   
  7.     public void rollback() throws Exception {  
  8.         throw new Exception("no support method");  
  9.     }  
  10.   
  11.     public void submit() throws Exception {  
  12.         User user = userService.getUser(0);  
  13.         user.setStauts(FOR_VERIFY_STATUS);  
  14.         userService.update(user);  
  15.     }  
  16.   
  17.     public int getStatus() {  
  18.         return COMMON_STATUS;  
  19.     }  
  20. }  



待審覈的用戶WaitForVerifyUser.java 

Java代碼  收藏代碼
  1.    
  2. public class WaitForVerifyUser implements UserState {  
  3.   
  4.     public void pass() throws Exception {  
  5.         User user = userService.getUser(0);  
  6.         user.setStauts(VIP_STATUS);  
  7.         userService.update(user);  
  8.     }  
  9.   
  10.     public void rollback() throws Exception {  
  11.         User user = userService.getUser(0);  
  12.         user.setStauts(COMMON_STATUS);  
  13.         userService.update(user);  
  14.     }  
  15.   
  16.     public void submit() throws Exception {  
  17.         throw new Exception("no support method");  
  18.     }  
  19.   
  20.     public int getStatus() {  
  21.         return VIP_STATUS;  
  22.     }  
  23. }  


審覈通過的用戶,vip VipUser.java 

Java代碼  收藏代碼
  1.    
  2. public class VipUser implements UserState {  
  3.   
  4.     public void pass() throws Exception {  
  5.         throw new Exception("no support method");  
  6.     }  
  7.   
  8.     public void rollback() throws Exception {  
  9.         User user = userService.getUser(0);  
  10.         user.setStauts(COMMON_STATUS);  
  11.         userService.update(user);  
  12.     }  
  13.   
  14.     public void submit() throws Exception {  
  15.         throw new Exception("no support method");  
  16.     }  
  17.   
  18.     public int getStatus() {  
  19.         return FOR_VERIFY_STATUS;  
  20.     }  
  21. }  



根據用戶的status的返回不同的UserState 

Java代碼  收藏代碼
  1.    
  2. public class UserStateFactory {  
  3.     static List list = null;  
  4.     static {  
  5.         list = new ArrayList();  
  6.         list.add(new NotSubmitUser());  
  7.         list.add(new VipUser());  
  8.         list.add(new WaitForVerifyUser());  
  9.   
  10.     }  
  11.   
  12.     public static UserState getUserState(int status) {  
  13.         for (UserState state : list) {  
  14.             if (state.getStatus() == status)  
  15.                 return state;  
  16.         }  
  17.         return null;  
  18.     }  
  19. }  



[size=small;]狀態模式操作是固定的,但是接受者類不相同。多態性的原則實際執行哪個方法不僅取決與方法簽名,還取決與操作的接受者類。 

該例子只是state模式的一個場景的應用,比較具體。 
狀態模式的優點:1.非常好的擴展性---假設增加一個用戶組:當vip用戶的信用達到一定程度後,升級到永久的vip。這時只需另外添加一個狀態類,對原來的代碼並不需要做改動。 
2.代碼結構清晰,不同出錯。即程序健壯--除UserStateFactory的getUserState(int status)外,其他方法的邏輯非常的簡單,都不包含局部變量。如果程序不需要持久化到數據庫,也不需要getUserState(int status),該方法是狀態模式內容之外的 

用狀態模式類的數量會大大的增加。 

說明:該例子只是狀態模式的一個應用,並不是狀態模式,是屬於比較具體。[/size] 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章