成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

設計模式系列—狀態模式

開發 前端
本篇和大家一起來學習狀態模式相關內容。

 模式定義

對有狀態的對象,把復雜的“判斷邏輯”提取到不同的狀態對象中,允許狀態對象在其內部狀態發生改變時改變其行為。

狀態模式把受環境改變的對象行為包裝在不同的狀態對象里,其意圖是讓一個對象在其內部狀態改變的時候,其行為也隨之改變?,F在我們來分析其基本結構和實現方法。

模板實現如下:

  1. package com.niuh.designpattern.state.v1; 
  2.  
  3. /** 
  4.  * <p> 
  5.  * 狀態模式 
  6.  * </p> 
  7.  */ 
  8. public class StatePattern { 
  9.  
  10.     public static void main(String[] args) { 
  11.         //創建環境   
  12.         Context context = new Context(); 
  13.         //處理請求 
  14.         context.Handle(); 
  15.         context.Handle(); 
  16.         context.Handle(); 
  17.         context.Handle(); 
  18.     } 
  19.  
  20. //抽象狀態類 
  21. abstract class State { 
  22.     public abstract void Handle(Context context); 
  23.  
  24. //具體狀態A類 
  25. class ConcreteStateA extends State { 
  26.     public void Handle(Context context) { 
  27.         System.out.println("當前狀態是 A."); 
  28.         context.setState(new ConcreteStateB()); 
  29.     } 
  30.  
  31. //具體狀態B類 
  32. class ConcreteStateB extends State { 
  33.     public void Handle(Context context) { 
  34.         System.out.println("當前狀態是 B."); 
  35.         context.setState(new ConcreteStateA()); 
  36.     } 
  37.  
  38. //環境類 
  39. class Context { 
  40.     private State state; 
  41.  
  42.     //定義環境類的初始狀態 
  43.     public Context() { 
  44.         this.state = new ConcreteStateA(); 
  45.     } 
  46.  
  47.     //設置新狀態 
  48.     public void setState(State state) { 
  49.         this.state = state; 
  50.     } 
  51.  
  52.     //讀取狀態 
  53.     public State getState() { 
  54.         return (state); 
  55.     } 
  56.  
  57.     //對請求做處理 
  58.     public void Handle() { 
  59.         state.Handle(this); 
  60.     } 

輸出結果如下:

  • 當前狀態是 A.
  • 當前狀態是 B.
  • 當前狀態是 A.
  • 當前狀態是 B.

解決的問題

對象的行為依賴于它的狀態(屬性),并且可以根據它的狀態改變而改變它的相關行為。

 

模式組成

實例說明

實例概況

用“狀態模式”設計一個多線程的狀態轉換程序。

 

分析:多線程存在 5 種狀態,分別為新建狀態、就緒狀態、運行狀態、阻塞狀態和死亡狀態,各個狀態當遇到相關方法調用或事件觸發時會轉換到其他狀態,其狀態轉換規律如下所示:

現在先定義一個抽象狀態類(TheadState),然后為上圖的每個狀態設計一個具體狀態類,它們是新建狀態(New)、就緒狀態(Runnable )、運行狀態(Running)、阻塞狀態(Blocked)和死亡狀態(Dead),每個狀態中有觸發它們轉變狀態的方法,環境類(ThreadContext)中先生成一個初始狀態(New),并提供相關觸發方法,下圖所示是線程狀態轉換程序的結構圖:

使用步驟

 

步驟1:定義抽象狀態類:線程狀態

  1. abstract class ThreadState { 
  2.     //狀態名 
  3.     protected String stateName; 

步驟2: 定義具體的狀態類

  1. //具體狀態類:新建狀態 
  2. class New extends ThreadState { 
  3.     public New() { 
  4.         stateName = "新建狀態"
  5.         System.out.println("當前線程處于:新建狀態."); 
  6.     } 
  7.  
  8.     public void start(ThreadContext hj) { 
  9.         System.out.print("調用start()方法-->"); 
  10.         if (stateName.equals("新建狀態")) { 
  11.             hj.setState(new Runnable()); 
  12.         } else { 
  13.             System.out.println("當前線程不是新建狀態,不能調用start()方法."); 
  14.         } 
  15.     } 
  16.  
  17. //具體狀態類:就緒狀態 
  18. class Runnable extends ThreadState { 
  19.     public Runnable() { 
  20.         stateName = "就緒狀態"
  21.         System.out.println("當前線程處于:就緒狀態."); 
  22.     } 
  23.  
  24.     public void getCPU(ThreadContext hj) { 
  25.         System.out.print("獲得CPU時間-->"); 
  26.         if (stateName.equals("就緒狀態")) { 
  27.             hj.setState(new Running()); 
  28.         } else { 
  29.             System.out.println("當前線程不是就緒狀態,不能獲取CPU."); 
  30.         } 
  31.     } 
  32.  
  33. //具體狀態類:運行狀態 
  34. class Running extends ThreadState { 
  35.     public Running() { 
  36.         stateName = "運行狀態"
  37.         System.out.println("當前線程處于:運行狀態."); 
  38.     } 
  39.  
  40.     public void suspend(ThreadContext hj) { 
  41.         System.out.print("調用suspend()方法-->"); 
  42.         if (stateName.equals("運行狀態")) { 
  43.             hj.setState(new Blocked()); 
  44.         } else { 
  45.             System.out.println("當前線程不是運行狀態,不能調用suspend()方法."); 
  46.         } 
  47.     } 
  48.  
  49.     public void stop(ThreadContext hj) { 
  50.         System.out.print("調用stop()方法-->"); 
  51.         if (stateName.equals("運行狀態")) { 
  52.             hj.setState(new Dead()); 
  53.         } else { 
  54.             System.out.println("當前線程不是運行狀態,不能調用stop()方法."); 
  55.         } 
  56.     } 
  57.  
  58. //具體狀態類:阻塞狀態 
  59. class Blocked extends ThreadState { 
  60.     public Blocked() { 
  61.         stateName = "阻塞狀態"
  62.         System.out.println("當前線程處于:阻塞狀態."); 
  63.     } 
  64.  
  65.     public void resume(ThreadContext hj) { 
  66.         System.out.print("調用resume()方法-->"); 
  67.         if (stateName.equals("阻塞狀態")) { 
  68.             hj.setState(new Runnable()); 
  69.         } else { 
  70.             System.out.println("當前線程不是阻塞狀態,不能調用resume()方法."); 
  71.         } 
  72.     } 
  73.  
  74. //具體狀態類:死亡狀態 
  75. class Dead extends ThreadState { 
  76.     public Dead() { 
  77.         stateName = "死亡狀態"
  78.         System.out.println("當前線程處于:死亡狀態."); 
  79.     } 

步驟3:定義環境類

  1. class ThreadContext { 
  2.     private ThreadState state; 
  3.  
  4.     ThreadContext() { 
  5.         state = new New(); 
  6.     } 
  7.  
  8.     public void setState(ThreadState state) { 
  9.         this.state = state; 
  10.     } 
  11.  
  12.     public ThreadState getState() { 
  13.         return state; 
  14.     } 
  15.  
  16.     public void start() { 
  17.         ((New) state).start(this); 
  18.     } 
  19.  
  20.     public void getCPU() { 
  21.         ((Runnable) state).getCPU(this); 
  22.     } 
  23.  
  24.     public void suspend() { 
  25.         ((Running) state).suspend(this); 
  26.     } 
  27.  
  28.     public void stop() { 
  29.         ((Running) state).stop(this); 
  30.     } 
  31.  
  32.     public void resume() { 
  33.         ((Blocked) state).resume(this); 
  34.     } 

輸出結果

  • 當前線程處于:新建狀態.
  • 調用start()方法-->當前線程處于:就緒狀態.
  • 獲得CPU時間-->當前線程處于:運行狀態.
  • 調用suspend()方法-->當前線程處于:阻塞狀態.
  • 調用resume()方法-->當前線程處于:就緒狀態.
  • 獲得CPU時間-->當前線程處于:運行狀態.
  • 調用stop()方法-->當前線程處于:死亡狀態.

優點

  1. 狀態模式將與特定狀態相關的行為局部化到一個狀態中,并且將不同狀態的行為分割開來,滿足“單一職責原則”。
  2. 減少對象間的相互依賴。將不同的狀態引入獨立的對象中會使得狀態轉換變得更加明確,且減少對象間的相互依賴。
  3. 有利于程序的擴展。通過定義新的子類很容易地增加新的狀態和轉換。

缺點

  1. 狀態模式的使用必然會增加系統的類與對象的個數。
  2. 狀態模式的結構與實現都較為復雜,如果使用不當會導致程序結構和代碼的混亂。

應用場景

通常在以下情況下可以考慮使用狀態模式。

  • 當一個對象的行為取決于它的狀態,并且它必須在運行時根據狀態改變它的行為時,就可以考慮使用狀態模式。
  • 一個操作中含有龐大的分支結構,并且這些分支決定于對象的狀態時。

狀態模式的擴展

 

在有些情況下,可能有多個環境對象需要共享一組狀態,這時需要引入享元模式,將這些具體狀態對象放在集合中供程序共享,其結構圖如下:

分析:共享狀態模式的不同之處是在環境類中增加了一個 HashMap 來保存相關狀態,當需要某種狀態時可以從中獲取,其程序代碼如下:

  1. package com.niuh.designpattern.state.v3; 
  2.  
  3. import java.util.HashMap; 
  4.  
  5. /** 
  6.  * <p> 
  7.  * 共享狀態模式 
  8.  * </p> 
  9.  */ 
  10. public class FlyweightStatePattern { 
  11.     public static void main(String[] args) { 
  12.         //創建環境  
  13.         ShareContext context = new ShareContext(); 
  14.         //處理請求 
  15.         context.Handle(); 
  16.         context.Handle(); 
  17.         context.Handle(); 
  18.         context.Handle(); 
  19.     } 
  20.  
  21. //抽象狀態類 
  22. abstract class ShareState { 
  23.     public abstract void Handle(ShareContext context); 
  24.  
  25. //具體狀態1類 
  26. class ConcreteState1 extends ShareState { 
  27.     public void Handle(ShareContext context) { 
  28.         System.out.println("當前狀態是: 狀態1"); 
  29.         context.setState(context.getState("2")); 
  30.     } 
  31.  
  32. //具體狀態2類 
  33. class ConcreteState2 extends ShareState { 
  34.     public void Handle(ShareContext context) { 
  35.         System.out.println("當前狀態是: 狀態2"); 
  36.         context.setState(context.getState("1")); 
  37.     } 
  38.  
  39. //環境類 
  40. class ShareContext { 
  41.     private ShareState state; 
  42.     private HashMap<String, ShareState> stateSet = new HashMap<String, ShareState>(); 
  43.  
  44.     public ShareContext() { 
  45.         state = new ConcreteState1(); 
  46.         stateSet.put("1", state); 
  47.         state = new ConcreteState2(); 
  48.         stateSet.put("2", state); 
  49.         state = getState("1"); 
  50.     } 
  51.  
  52.     //設置新狀態 
  53.     public void setState(ShareState state) { 
  54.         this.state = state; 
  55.     } 
  56.  
  57.     //讀取狀態 
  58.     public ShareState getState(String key) { 
  59.         ShareState s = (ShareState) stateSet.get(key); 
  60.         return s; 
  61.     } 
  62.  
  63.     //對請求做處理 
  64.     public void Handle() { 
  65.         state.Handle(this); 
  66.     } 

輸出結果如下

  • 當前狀態是: 狀態1
  • 當前狀態是: 狀態2
  • 當前狀態是: 狀態1
  • 當前狀態是: 狀態2

 

源碼中的應用

  1. #JDK中的狀態模式: 
  2. java.util.Iterator 
  3. # 通過FacesServlet控制, 行為取決于當前JSF生命周期的階段(狀態 
  4. javax.faces.lifecycle.LifeCycle#execute() 

PS:以上代碼提交在 Github :

https://github.com/Niuh-Study/niuh-designpatterns.git

責任編輯:姜華 來源: 今日頭條
相關推薦

2020-11-03 13:05:18

命令模式

2020-10-23 09:40:26

設計模式

2022-01-12 13:33:25

工廠模式設計

2020-10-20 13:33:00

建造者模式

2020-10-28 11:56:47

橋接模式

2020-11-09 08:20:33

解釋器模式

2021-10-26 00:21:19

設計模式建造者

2021-10-28 19:09:09

模式原型Java

2012-01-13 15:59:07

2020-11-05 09:38:07

中介者模式

2021-09-29 13:53:17

抽象工廠模式

2022-01-14 09:22:22

設計模式橋接

2020-10-19 09:28:00

抽象工廠模式

2020-10-21 14:29:15

原型模式

2021-06-09 08:53:34

設計模式策略模式工廠模式

2021-03-02 08:50:31

設計單例模式

2013-11-26 15:48:53

Android設計模式SDK

2012-08-30 09:07:33

設計模式

2020-11-02 10:41:33

備忘錄模式

2021-06-22 15:27:13

設計模式迭代器模式Java
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 91精品国产91久久久久久最新 | 日本精品视频 | 欧美日韩国产中文 | 精品九九久久 | 中文字幕韩在线第一页 | 狠狠色香婷婷久久亚洲精品 | 国产7777 | 午夜免费视频 | 午夜网址| 免费在线观看h片 | 黄色一级片aaa | 国产精品视频一区二区三区 | 国产一区二区日韩 | www.久| 成人免费一区二区三区视频网站 | 精品久久99| 九九视频网 | 黄色一级电影在线观看 | 人人人干 | 丁香六月激情 | 午夜精品久久久久久久久久久久 | 黑人性hd| 欧美一区二区视频 | 范冰冰一级做a爰片久久毛片 | caoporn国产精品免费公开 | 午夜在线小视频 | 久久久www成人免费精品 | 日韩欧美在线播放 | 欧美网站一区二区 | 欧美精品一区三区 | 久久综合久色欧美综合狠狠 | 人人鲁人人莫人人爱精品 | 精品久久国产 | 超碰97人人人人人蜜桃 | 午夜视频在线观看一区二区 | 成人福利视频 | 一区二区三区国产 | 色网在线观看 | 国产一区二区欧美 | 精品国产一级 | 亚洲视频欧美视频 |