1. 程式人生 > >狀態模式-State-訂單狀態

狀態模式-State-訂單狀態

背景 pan rgs too top fonts toc @override tle

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

21. State(狀態) 技術分享圖片 意圖: 允許一個對象在其內部狀態改變時改變它的行為。對象看起來似乎修改了它的類。 解釋:
比如說對訂單的提交,第一次提交是成功的,但是第二次提交的時候就會是失敗的,因為其內部狀態已經改變,而外部都是“訂單”調用了“提交”方法,同一個行為,但是實質上造成的效果已經不同。 適用性: 一個對象的行為取決於它的狀態, 並且它必須在運行時刻根據狀態改變它的行為。 一個操作中含有龐大的多分支的條件語句,且這些分支依賴於該對象的狀態。這個狀態通常用一個或多個枚舉常量表示。通常, 有多個操作包含這一相同的條件結構。State模式將每一個條件分支放入一個獨立的類中。這使得你可以根據對象自身的情況將對象的狀態作為一個對象,這一對象可以不依賴於其他對象而獨立變化。

解釋:

行為取決於它的狀態,即是說由狀態決定行為,方法放在狀態類中,而狀態控制亦在狀態類中進行,譬如一個按鈕,按一次是開,按一次是關,同一個行為,但是由於其狀態的改變,而導致不同的結果。 一個操作中含有龐大的多分支的條件語句,且這些分支依賴於該對象的狀態。這個狀態通常用一個或多個枚舉常量表示。通常, 有多個操作包含這一相同的條件結構。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. abstract void modify(OrderContext orderContext);
  4. abstract void pay(OrderContext orderContext);
  5. }

具體狀態類 [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. @Override
  8. void modify(OrderContext orderContext) {
  9. System.out.println("訂單已修改");
  10. orderContext.setState(this);
  11. }
  12. @Override
  13. void pay(OrderContext orderContext) {
  14. System.out.println("預定狀態無法完成訂單!");
  15. }
  16. }
  17. class ConfirmedState extends OrderState {
  18. @Override
  19. void confirm(OrderContext orderContext) {
  20. System.out.println("訂單已確認,請勿重復確認");
  21. }
  22. @Override
  23. void modify(OrderContext orderContext) {
  24. System.out.println("訂單已修改,請再次確認");
  25. orderContext.setState(new OrderedState());
  26. }
  27. @Override
  28. void pay(OrderContext orderContext) {
  29. System.out.println("訂單已支付,無法再修改");
  30. orderContext.setState(new LockedState());
  31. }
  32. }
  33. class LockedState extends OrderState {
  34. @Override
  35. void confirm(OrderContext orderContext) {
  36. System.out.println("訂單已鎖定");
  37. }
  38. @Override
  39. void modify(OrderContext orderContext) {
  40. System.out.println("訂單已鎖定");
  41. }
  42. @Override
  43. void pay(OrderContext orderContext) {
  44. System.out.println("訂單已鎖定");
  45. }
  46. }

背景類 [java] view plain copy
  1. class OrderContext {
  2. OrderState state = null;
  3. //新建訂單設為已預定狀態
  4. OrderContext() {
  5. this.state = new OrderedState();
  6. }
  7. void setState(OrderState state) {
  8. this.state = state;
  9. }
  10. public void confirm() {
  11. state.confirm(this);
  12. }
  13. public void modify() {
  14. state.modify(this);
  15. }
  16. public void pay() {
  17. state.pay(this);
  18. }
  19. }
測試: [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. 訂單已鎖定

狀態模式-State-訂單狀態