偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

設(shè)計(jì)模式系列—狀態(tài)模式

開(kāi)發(fā) 前端
本篇和大家一起來(lái)學(xué)習(xí)狀態(tài)模式相關(guān)內(nèi)容。

 模式定義

對(duì)有狀態(tài)的對(duì)象,把復(fù)雜的“判斷邏輯”提取到不同的狀態(tài)對(duì)象中,允許狀態(tài)對(duì)象在其內(nèi)部狀態(tài)發(fā)生改變時(shí)改變其行為。

狀態(tài)模式把受環(huán)境改變的對(duì)象行為包裝在不同的狀態(tài)對(duì)象里,其意圖是讓一個(gè)對(duì)象在其內(nèi)部狀態(tài)改變的時(shí)候,其行為也隨之改變?,F(xiàn)在我們來(lái)分析其基本結(jié)構(gòu)和實(shí)現(xiàn)方法。

模板實(shí)現(xiàn)如下:

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

輸出結(jié)果如下:

  • 當(dāng)前狀態(tài)是 A.
  • 當(dāng)前狀態(tài)是 B.
  • 當(dāng)前狀態(tài)是 A.
  • 當(dāng)前狀態(tài)是 B.

解決的問(wèn)題

對(duì)象的行為依賴于它的狀態(tài)(屬性),并且可以根據(jù)它的狀態(tài)改變而改變它的相關(guān)行為。

 

模式組成

實(shí)例說(shuō)明

實(shí)例概況

用“狀態(tài)模式”設(shè)計(jì)一個(gè)多線程的狀態(tài)轉(zhuǎn)換程序。

 

分析:多線程存在 5 種狀態(tài),分別為新建狀態(tài)、就緒狀態(tài)、運(yùn)行狀態(tài)、阻塞狀態(tài)和死亡狀態(tài),各個(gè)狀態(tài)當(dāng)遇到相關(guān)方法調(diào)用或事件觸發(fā)時(shí)會(huì)轉(zhuǎn)換到其他狀態(tài),其狀態(tài)轉(zhuǎn)換規(guī)律如下所示:

現(xiàn)在先定義一個(gè)抽象狀態(tài)類(TheadState),然后為上圖的每個(gè)狀態(tài)設(shè)計(jì)一個(gè)具體狀態(tài)類,它們是新建狀態(tài)(New)、就緒狀態(tài)(Runnable )、運(yùn)行狀態(tài)(Running)、阻塞狀態(tài)(Blocked)和死亡狀態(tài)(Dead),每個(gè)狀態(tài)中有觸發(fā)它們轉(zhuǎn)變狀態(tài)的方法,環(huán)境類(ThreadContext)中先生成一個(gè)初始狀態(tài)(New),并提供相關(guān)觸發(fā)方法,下圖所示是線程狀態(tài)轉(zhuǎn)換程序的結(jié)構(gòu)圖:

使用步驟

 

步驟1:定義抽象狀態(tài)類:線程狀態(tài)

  1. abstract class ThreadState { 
  2.     //狀態(tài)名 
  3.     protected String stateName; 

步驟2: 定義具體的狀態(tài)類

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

步驟3:定義環(huán)境類

  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.     } 

輸出結(jié)果

  • 當(dāng)前線程處于:新建狀態(tài).
  • 調(diào)用start()方法-->當(dāng)前線程處于:就緒狀態(tài).
  • 獲得CPU時(shí)間-->當(dāng)前線程處于:運(yùn)行狀態(tài).
  • 調(diào)用suspend()方法-->當(dāng)前線程處于:阻塞狀態(tài).
  • 調(diào)用resume()方法-->當(dāng)前線程處于:就緒狀態(tài).
  • 獲得CPU時(shí)間-->當(dāng)前線程處于:運(yùn)行狀態(tài).
  • 調(diào)用stop()方法-->當(dāng)前線程處于:死亡狀態(tài).

優(yōu)點(diǎn)

  1. 狀態(tài)模式將與特定狀態(tài)相關(guān)的行為局部化到一個(gè)狀態(tài)中,并且將不同狀態(tài)的行為分割開(kāi)來(lái),滿足“單一職責(zé)原則”。
  2. 減少對(duì)象間的相互依賴。將不同的狀態(tài)引入獨(dú)立的對(duì)象中會(huì)使得狀態(tài)轉(zhuǎn)換變得更加明確,且減少對(duì)象間的相互依賴。
  3. 有利于程序的擴(kuò)展。通過(guò)定義新的子類很容易地增加新的狀態(tài)和轉(zhuǎn)換。

缺點(diǎn)

  1. 狀態(tài)模式的使用必然會(huì)增加系統(tǒng)的類與對(duì)象的個(gè)數(shù)。
  2. 狀態(tài)模式的結(jié)構(gòu)與實(shí)現(xiàn)都較為復(fù)雜,如果使用不當(dāng)會(huì)導(dǎo)致程序結(jié)構(gòu)和代碼的混亂。

應(yīng)用場(chǎng)景

通常在以下情況下可以考慮使用狀態(tài)模式。

  • 當(dāng)一個(gè)對(duì)象的行為取決于它的狀態(tài),并且它必須在運(yùn)行時(shí)根據(jù)狀態(tài)改變它的行為時(shí),就可以考慮使用狀態(tài)模式。
  • 一個(gè)操作中含有龐大的分支結(jié)構(gòu),并且這些分支決定于對(duì)象的狀態(tài)時(shí)。

狀態(tài)模式的擴(kuò)展

 

在有些情況下,可能有多個(gè)環(huán)境對(duì)象需要共享一組狀態(tài),這時(shí)需要引入享元模式,將這些具體狀態(tài)對(duì)象放在集合中供程序共享,其結(jié)構(gòu)圖如下:

分析:共享狀態(tài)模式的不同之處是在環(huán)境類中增加了一個(gè) HashMap 來(lái)保存相關(guān)狀態(tài),當(dāng)需要某種狀態(tài)時(shí)可以從中獲取,其程序代碼如下:

  1. package com.niuh.designpattern.state.v3; 
  2.  
  3. import java.util.HashMap; 
  4.  
  5. /** 
  6.  * <p> 
  7.  * 共享狀態(tài)模式 
  8.  * </p> 
  9.  */ 
  10. public class FlyweightStatePattern { 
  11.     public static void main(String[] args) { 
  12.         //創(chuàng)建環(huán)境  
  13.         ShareContext context = new ShareContext(); 
  14.         //處理請(qǐng)求 
  15.         context.Handle(); 
  16.         context.Handle(); 
  17.         context.Handle(); 
  18.         context.Handle(); 
  19.     } 
  20.  
  21. //抽象狀態(tài)類 
  22. abstract class ShareState { 
  23.     public abstract void Handle(ShareContext context); 
  24.  
  25. //具體狀態(tài)1類 
  26. class ConcreteState1 extends ShareState { 
  27.     public void Handle(ShareContext context) { 
  28.         System.out.println("當(dāng)前狀態(tài)是: 狀態(tài)1"); 
  29.         context.setState(context.getState("2")); 
  30.     } 
  31.  
  32. //具體狀態(tài)2類 
  33. class ConcreteState2 extends ShareState { 
  34.     public void Handle(ShareContext context) { 
  35.         System.out.println("當(dāng)前狀態(tài)是: 狀態(tài)2"); 
  36.         context.setState(context.getState("1")); 
  37.     } 
  38.  
  39. //環(huán)境類 
  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.     //設(shè)置新?tīng)顟B(tài) 
  53.     public void setState(ShareState state) { 
  54.         this.state = state; 
  55.     } 
  56.  
  57.     //讀取狀態(tài) 
  58.     public ShareState getState(String key) { 
  59.         ShareState s = (ShareState) stateSet.get(key); 
  60.         return s; 
  61.     } 
  62.  
  63.     //對(duì)請(qǐng)求做處理 
  64.     public void Handle() { 
  65.         state.Handle(this); 
  66.     } 

輸出結(jié)果如下

  • 當(dāng)前狀態(tài)是: 狀態(tài)1
  • 當(dāng)前狀態(tài)是: 狀態(tài)2
  • 當(dāng)前狀態(tài)是: 狀態(tài)1
  • 當(dāng)前狀態(tài)是: 狀態(tài)2

 

源碼中的應(yīng)用

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

PS:以上代碼提交在 Github :

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

責(zé)任編輯:姜華 來(lái)源: 今日頭條
相關(guān)推薦

2022-01-12 13:33:25

工廠模式設(shè)計(jì)

2020-11-03 13:05:18

命令模式

2020-10-23 09:40:26

設(shè)計(jì)模式

2021-09-29 13:53:17

抽象工廠模式

2022-01-14 09:22:22

設(shè)計(jì)模式橋接

2020-10-19 09:28:00

抽象工廠模式

2020-10-21 14:29:15

原型模式

2021-03-02 08:50:31

設(shè)計(jì)單例模式

2013-11-26 15:48:53

Android設(shè)計(jì)模式SDK

2021-06-09 08:53:34

設(shè)計(jì)模式策略模式工廠模式

2020-10-28 11:56:47

橋接模式

2020-11-09 08:20:33

解釋器模式

2021-10-28 19:09:09

模式原型Java

2012-01-13 15:59:07

2020-11-05 09:38:07

中介者模式

2021-10-26 00:21:19

設(shè)計(jì)模式建造者

2020-10-20 13:33:00

建造者模式

2012-08-30 09:07:33

設(shè)計(jì)模式

2020-10-25 08:56:21

適配器模式

2021-03-05 07:57:41

設(shè)計(jì)模式橋接
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)