JAVA設計模式之 狀態模式【State Pattern】
一、概述
當系統中某個物件存在多個狀態,這些狀態之間可以進行轉換,而且物件在不同狀態下行為不相同時可以使用狀態模式。狀態模式將一個物件的狀態從該物件中分離出來,封裝到專門的狀態類中,使得物件狀態可以靈活變化。狀態模式是一種物件行為型模式。
二、適用場景
用於解決系統中複雜物件的多種狀態轉換以及不同狀態下行為的封裝問題。簡單說就是處理物件的多種狀態及其相互轉換。
三、UML類圖
四、參與者
1>、AbstractState(抽象狀態類):
在抽象狀態類中定義申明瞭不同狀態下的行為抽象方法,而由子類(不同的狀態子類)中實現不同的行為操作。
2>、ConcreteState(實現具體狀態下行為的狀態子類):
抽象狀態類的子類,每一個子類實現一個與環境類(Context)的一個狀態相關的行為,每一個具體的狀態類對應環境的一種具體狀態,不同的具體狀態其行為有所不同。
3>、Context(擁有狀態物件的環境類):
擁有狀態屬性,因環境的多樣性,它可擁有不同的狀態,且在不同狀態下行為也不一樣。在環境類中維護一個抽象的狀態例項,這個例項定義當前環境的狀態(setState()方法),而將具體的狀態行為分離出來由不同的狀態子類去完成。
五、用例學習
1、抽象狀態類:State.java
/**
* JAVA設計模式之 狀態模式
* 抽象狀態類
* @author lvzb.software@qq.com
*
*/
public abstract class State {
/**
* 狀態行為抽象方法,由具體的狀態子類去實現不同的行為邏輯
*/
public abstract void Behavior();
}
2、具體狀態子類A:ConcreteStateA.java
/**
* 具體的狀態子類A
* @author lvzb.software@qq.com
*/
public class ConcreteStateA extends State {
@Override
public void Behavior() {
// 狀態A 的業務行為, 及當為該狀態下時,能幹什麼
// 如:手機在未欠費停機狀態下, 能正常撥打電話
System.out.println("手機在未欠費停機狀態下, 能正常撥打電話");
}
}
3、具體狀態子類B:ConcreteStateB.java
/**
* 具體的狀態子類B
* @author lvzb.software@qq.com
*
*/
public class ConcreteStateB extends State {
@Override
public void Behavior() {
// 狀態B 的業務行為, 及當為該狀態下時,能幹什麼
// 如:手機在欠費停機狀態下, 不 能撥打電話
System.out.println("手機在欠費停機狀態下, 不能撥打電話");
}
}
4、擁有狀態物件的環境類:Context.java/**
* 環境/上下文類<br/>
* 擁有狀態物件,且可以完成狀態間的轉換 [狀態的改變/切換 在環境類中實現]
* @author lvzb.software@qq.com
*
*/
public class Context {
// 維護一個抽象狀態物件的引用
private State state;
/*
* 模擬手機的話費屬性<br/>
* 環境狀態如下:
* 1>、當 bill >= 0.00$ : 狀態正常 還能撥打電話
* 2>、當 bill < 0.00$ : 手機欠費 不能撥打電話
*/
private double bill;
/**
* 環境處理函式,呼叫狀態例項行為 完成業務邏輯<br/>
* 根據不同的狀態例項引用 在不同狀態下處理不同的行為
*/
public void Handle(){
checkState();
state.Behavior();
}
/**
* 檢查環境狀態:狀態的改變/切換 在環境類中實現
*/
private void checkState(){
if(bill >= 0.00){
setState(new ConcreteStateA());
} else {
setState(new ConcreteStateB());
}
}
/**
* 設定環境狀態<br/>
* 私有方法,目的是 讓環境的狀態由系統環境自身來控制/切換,外部使用者無需關心環境內部的狀態
* @param state
*/
private void setState(State state){
this.state = state;
}
public double getBill() {
return bill;
}
public void setBill(double bill) {
this.bill = bill;
}
}
5、測試客戶端呼叫類:Client.javapublic class Client {
public static void main(String[] args) {
Context context = new Context();
context.setBill(5.50);
System.out.println("當前話費餘額:" + context.getBill() + "$");
context.Handle();
context.setBill(-1.50);
System.out.println("當前話費餘額:" + context.getBill() + "$");
context.Handle();
context.setBill(50.00);
System.out.println("當前話費餘額:" + context.getBill() + "$");
context.Handle();
}
}
6、程式執行結果:當前話費餘額:5.5$
手機在未欠費停機狀態下, 能正常撥打電話
當前話費餘額:-1.5$
手機在欠費停機狀態下, 不能撥打電話
當前話費餘額:50.0$
手機在未欠費停機狀態下, 能正常撥打電話
六、擴充套件
狀態模式中 關於狀態的切換有兩種不同的實現方式
方式一:狀態的改變/切換 在環境類中實現。 如上面的用例程式碼Context類中的checkState()方法。
/**
* 檢查環境狀態:狀態的改變/切換 在環境類中實現
*/
private void checkState(){
if(bill >= 0.00){
setState(new ConcreteStateA());
} else {
setState(new ConcreteStateB());
}
}
方式二:狀態的改變/切換 在具體的狀態子類中實現。
實現步驟如下:
1> 在環境類Context類中 初始化一個狀態例項物件,並將環境Context物件作為子類狀態的構造引數傳遞到具體的狀態子類例項中。
如在Context.java類中:
// 設定初始狀態
this.state = new ConcreteStateA(this);
2> 在具體的子類狀態類中根據構造進來的context物件,通過呼叫context物件的屬性值進行業務邏輯判斷 進行狀態的檢查和切換。
如在 具體的狀態子類ConcreteStateA.java類中:
/**
* 具體的狀態子類A
* @author lvzb.software@qq.com
*/
public class ConcreteStateA extends State {
private Context ctx;
public ConcreteStateA(Context context){
ctx = context;
}
@Override
public void Behavior() {
// 狀態A 的業務行為, 及當為該狀態下時,能幹什麼
// 如:手機在未欠費停機狀態下, 能正常撥打電話
System.out.println("手機在未欠費停機狀態下, 能正常撥打電話");
checkState();
}
/**
* 檢查狀態 是否需要進行狀態的轉換<br/>
* 狀態的切換由具體狀態子類中實現
*/
private void checkState(){
if (ctx.getBill() < 0.00) {
ctx.setState(new ConcreteStateB(ctx));
}
}
}
相關文章
- 設計模式-狀態模式(State Pattern)設計模式
- 設計模式之策略模式和狀態模式(strategy pattern & state pattern)設計模式
- 設計模式之狀態模式(State)設計模式
- 使用C# (.NET Core) 實現狀態設計模式 (State Pattern)C#設計模式
- 折騰Java設計模式之狀態模式Java設計模式
- 設計模式之——狀態模式設計模式
- PHP 設計模式之狀態模式PHP設計模式
- 設計模式20之狀態模式設計模式
- C#設計模式之狀態模式C#設計模式
- 設計模式漫談之狀態模式設計模式
- 設計模式之代理模式(proxy pattern)設計模式
- 設計模式:狀態模式設計模式
- 設計模式-狀態模式設計模式
- Unity【話大】設計模式之狀態模式Unity設計模式
- 設計模式之單例模式(Singleton Pattern)設計模式單例
- Java進階篇設計模式之十二 ---- 備忘錄模式和狀態模式Java設計模式
- python設計模式狀態模式Python設計模式
- 設計模式(十五)狀態模式設計模式
- 4/24 設計模式之命令設計模式 Command Pattern設計模式
- 1/24 設計模式之策略設計模式 Strategy Pattern設計模式
- 設計模式之介面卡模式(adapter pattern)設計模式APT
- 設計模式之裝飾器模式(decorator pattern)設計模式
- 設計模式之觀察者模式(Observer Pattern)設計模式Server
- 設計模式(二十一)----行為型模式之狀態模式設計模式
- 《Head First 設計模式》:狀態模式設計模式
- 簡說設計模式——狀態模式設計模式
- 極簡設計模式-狀態模式設計模式
- GoLang設計模式14 - 狀態模式Golang設計模式
- python設計模式【9】-狀態模式Python設計模式
- 設計模式之委派模式(Delegate Pattern)深入淺出設計模式
- 設計模式之狀態模式(三分鐘學會一個設計模式)設計模式
- 23種設計模式(七)-狀態設計模式設計模式
- 設計模式第八講-狀態模式設計模式
- 設計模式--直譯器模式和狀態模式設計模式
- 設計模式系列之工廠模式三兄弟(Factory Pattern)設計模式
- 12/24 設計模式之介面卡模式 Adapter Pattern設計模式APT
- 設計模式--建造者模式(Builder Pattern)設計模式UI
- 設計模式--原型模式(Prototype Pattern)設計模式原型
- 設計模式--裝飾模式(Decorator Pattern)設計模式