先簡單介紹一下狀態模式:將與狀態有關處理邏輯分散到代表對象狀態各個類中!
狀態之間的改變都對應一個動作,一個動作可能對應多個狀態的改變(動作來描述。可能不是特別準確),如提交,審覈....
state模式的兩個原則:
1.有幾個動作就有幾個方法,一個動作可能對應多個狀態轉換,這些方法都定義在同一個接口裏。
2.有幾個狀態就有幾個實現上述接口的類。
用戶升級vip例子:首先用戶必須是註冊用戶,普通用戶升級vip需要提交真實的個人信息,工作人員根據提交信息的真實性進行審覈。審覈通過成爲vip用戶,審覈未通過,可以再次申請。升級到vip以後,如果查到有違反紀律的。降級到普通用戶。需要重新提交vip申請。
[img]/upload/p_w_upload/50463/5d802be4-ebcf-3bc8-8e1e-4f6c4b163c13.jpg" alt="[/img]
先定義接口UserState
- public interface UserState {
- public UserService userService = new UserService();
- // 狀態爲0代表普通用戶,這些狀態主要用於持久化到數據
- public final static int COMMON_STATUS = 0;
- // 狀態爲1代表待審覈用戶
- public final static int FOR_VERIFY_STATUS = 1;
- // 狀態爲2是代表vip用戶
- public final static int VIP_STATUS = 2;
- // 提交信息
- public void submit() throws Exception;
- // 審覈沒通過
- public void rollback() throws Exception;
- // 審覈通過
- public void pass() throws Exception;
- public int getStatus();
代表各個狀態的類
未提交信息的用戶NotSubmitUser.java
- public class NotSubmitUser implements UserState {
- public void pass() throws Exception {
- throw new Exception("no support method");
- }
- public void rollback() throws Exception {
- throw new Exception("no support method");
- }
- public void submit() throws Exception {
- User user = userService.getUser(0);
- user.setStauts(FOR_VERIFY_STATUS);
- userService.update(user);
- }
- public int getStatus() {
- return COMMON_STATUS;
- }
- }
待審覈的用戶WaitForVerifyUser.java
- public class WaitForVerifyUser implements UserState {
- public void pass() throws Exception {
- User user = userService.getUser(0);
- user.setStauts(VIP_STATUS);
- userService.update(user);
- }
- public void rollback() throws Exception {
- User user = userService.getUser(0);
- user.setStauts(COMMON_STATUS);
- userService.update(user);
- }
- public void submit() throws Exception {
- throw new Exception("no support method");
- }
- public int getStatus() {
- return VIP_STATUS;
- }
- }
審覈通過的用戶,vip VipUser.java
- public class VipUser implements UserState {
- public void pass() throws Exception {
- throw new Exception("no support method");
- }
- public void rollback() throws Exception {
- User user = userService.getUser(0);
- user.setStauts(COMMON_STATUS);
- userService.update(user);
- }
- public void submit() throws Exception {
- throw new Exception("no support method");
- }
- public int getStatus() {
- return FOR_VERIFY_STATUS;
- }
- }
根據用戶的status的返回不同的UserState
- public class UserStateFactory {
- static List list = null;
- static {
- list = new ArrayList();
- list.add(new NotSubmitUser());
- list.add(new VipUser());
- list.add(new WaitForVerifyUser());
- }
- public static UserState getUserState(int status) {
- for (UserState state : list) {
- if (state.getStatus() == status)
- return state;
- }
- return null;
- }
- }
[size=small;]狀態模式操作是固定的,但是接受者類不相同。多態性的原則實際執行哪個方法不僅取決與方法簽名,還取決與操作的接受者類。
該例子只是state模式的一個場景的應用,比較具體。
狀態模式的優點:1.非常好的擴展性---假設增加一個用戶組:當vip用戶的信用達到一定程度後,升級到永久的vip。這時只需另外添加一個狀態類,對原來的代碼並不需要做改動。
2.代碼結構清晰,不同出錯。即程序健壯--除UserStateFactory的getUserState(int status)外,其他方法的邏輯非常的簡單,都不包含局部變量。如果程序不需要持久化到數據庫,也不需要getUserState(int status),該方法是狀態模式內容之外的
用狀態模式類的數量會大大的增加。
說明:該例子只是狀態模式的一個應用,並不是狀態模式,是屬於比較具體。[/size]