簡介
- 狀態(tài)模式是一種行為型設(shè)計模式,用于處理對象在不同狀態(tài)下的行為變化。它將對象的行為封裝在不同狀態(tài)類中,通過狀態(tài)的切換實現(xiàn)不同行為的觸發(fā)。
- 本文將介紹狀態(tài)模式的基本概念、應(yīng)用場景以及優(yōu)勢與適用性。
狀態(tài)模式基礎(chǔ)
定義狀態(tài)接口或抽象類
public abstract class State
{
public abstract void WriteProgram(Work w);
}
實現(xiàn)具體狀態(tài)類
//上午工作狀態(tài)
public class ForenoonState : State
{
public override void WriteProgram(Work w)
{
//這里的判斷就是決定要用那種行為展現(xiàn)出來,如果 不符合當(dāng)前狀態(tài),那么就去到已經(jīng)設(shè)置好的下一個具體狀態(tài)類中進(jìn)行相同的操作。
if (w.hour < 12)
{
Console.WriteLine("當(dāng)前時間:{0}點 上午工作,精神百倍",w.Hour);
}
else
{
w.SetState(new NoonState());w.WriteProgram();
}
}
}
//中午工作狀態(tài)
public class NoonState : State
{
public override void WriteProgram(Work w)
{
if (w.hour < 13)
{
Console.WriteLine("當(dāng)前時間:{0}點 餓了,想吃飯;犯困,想睡覺。", w.Hour);
}
else
{
w.SetState(new AfternoonState()); w.WriteProgram();
}
}
}
//下午工作狀態(tài)
public class AfternoonState : State
{
public override void WriteProgram(Work w)
{
if (w.hour < 17)
{
Console.WriteLine("當(dāng)前時間:{0}點 下午狀態(tài)還不錯,繼續(xù)努力", w.Hour);
}
else
{
w.SetState(new EveningState()); w.WriteProgram();
}
}
}
//晚上工作狀態(tài)
public class EveningState : State
{
public override void WriteProgram(Work w)
{
if (w.finish )
{
w.SetState(new RestState());w.WriteProgram();//完成任務(wù)就轉(zhuǎn)成下班狀態(tài)
}
else
{
if (w.hour <21)
{
Console.WriteLine("當(dāng)前時間:{0}點 加班了,加班人累啊", w.Hour);
}
else
{
w.SetState(new SleepingState()); w.WriteProgram();//超過21點,轉(zhuǎn)入睡眠狀態(tài)
}
}
}
}
//睡眠狀態(tài)
public class SleepingState:State
{
public override void WriteProgram(Work w)
{
Console.WriteLine("當(dāng)前時間:{0}點 不行了,睡著了", w.Hour);
}
}
//下班休息狀態(tài)
public class RestState : State
{
public override void WriteProgram(Work w)
{
Console.WriteLine("當(dāng)前時間:{0}點 不行了,睡著了", w.Hour);
}
}
具體工作類:
public class Work
{
public State current;
public Work()
{
current = new ForenoonState(); //初始化為上午9點開始上班
}
public double hour;//小時鐘,狀態(tài)轉(zhuǎn)換的依據(jù)
public bool finish = false;//完成任務(wù)屬性,是否能下班的依據(jù)
//這個方法主要就是把具體的狀態(tài)類給進(jìn)來,然后讓下面的方法去使用
public void SetState(State s) //得到狀態(tài)
{
current = s;
}
//下面這個方法從始至終都沒有發(fā)生改變,改變是其內(nèi)部具體的展現(xiàn)值。
public void WriteProgram()
{
current.WriteProgram(this);
}
}
上下文類與狀態(tài)轉(zhuǎn)換
上下文類的定義和作用
- 上下文類包含狀態(tài)對象的引用,并將具體行為委托給當(dāng)前狀態(tài)對象執(zhí)行。
- 示例代碼:
// 上下文類
public class Context {
private State currentState;
public void setCurrentState(State state) {
this.currentState = state;
}
public void request() {
// 委托當(dāng)前狀態(tài)對象執(zhí)行行為
currentState.handle();
}
}
狀態(tài)轉(zhuǎn)換及觸發(fā)條件
- 狀態(tài)轉(zhuǎn)換指從一個狀態(tài)切換到另一個狀態(tài)的過程。
- 觸發(fā)條件是使?fàn)顟B(tài)轉(zhuǎn)換發(fā)生的條件。
- 示例代碼:
// 具體狀態(tài)類A
public class ConcreteStateA implements State {
// ...
@Override
public void handle() {
// 具體狀態(tài)A的行為邏輯
// 狀態(tài)轉(zhuǎn)換及觸發(fā)條件
if (/*觸發(fā)條件*/) {
context.setCurrentState(new ConcreteStateB());
}
}
}
狀態(tài)模式的優(yōu)勢與適用性
優(yōu)點一:可維護(hù)的代碼
- 狀態(tài)模式將每個狀態(tài)的行為邏輯封裝在獨立的狀態(tài)類中,易于理解和維護(hù)。
優(yōu)點二:清晰的狀態(tài)管理
- 狀態(tài)模式通過上下文類進(jìn)行狀態(tài)轉(zhuǎn)換和行為委托,使?fàn)顟B(tài)管理更加清晰明確。
適用場景一:對象擁有多個狀態(tài)
- 當(dāng)對象具有多個狀態(tài)且不同狀態(tài)下表現(xiàn)出不同行為時,可以使用狀態(tài)模式進(jìn)行狀態(tài)管理和行為切換。
適用場景二:狀態(tài)轉(zhuǎn)換頻繁且復(fù)雜
- 當(dāng)狀態(tài)轉(zhuǎn)換頻繁且存在復(fù)雜的觸發(fā)條件時,狀態(tài)模式能夠提供一種結(jié)構(gòu)化的方式來管理狀態(tài)轉(zhuǎn)換。
具體業(yè)務(wù)場景應(yīng)用:電商訂單狀態(tài)切換
?
為了演示訂單狀態(tài)管理的狀態(tài)模式業(yè)務(wù)代碼,我將使用Java語言來實現(xiàn)。以下是一個簡單的示例:
首先,我們定義訂單狀態(tài)接口 OrderState
,其中包含了處理訂單狀態(tài)的方法 handle()
:
// 訂單狀態(tài)接口
public interface OrderState {
void handle();
}
然后,我們創(chuàng)建具體的訂單狀態(tài)類,包括待支付狀態(tài)、已支付狀態(tài)、待發(fā)貨狀態(tài)和已發(fā)貨狀態(tài)。每個狀態(tài)類實現(xiàn)了訂單狀態(tài)接口,并根據(jù)相應(yīng)的狀態(tài)實現(xiàn)了自己的行為邏輯。
// 待支付狀態(tài)類
public class PendingPaymentState implements OrderState {
@Override
public void handle() {
System.out.println("當(dāng)前訂單狀態(tài):待支付");
// 處理待支付狀態(tài)的邏輯
}
}
// 已支付狀態(tài)類
public class PaidState implements OrderState {
@Override
public void handle() {
System.out.println("當(dāng)前訂單狀態(tài):已支付");
// 處理已支付狀態(tài)的邏輯
}
}
// 待發(fā)貨狀態(tài)類
public class ToBeShippedState implements OrderState {
@Override
public void handle() {
System.out.println("當(dāng)前訂單狀態(tài):待發(fā)貨");
// 處理待發(fā)貨狀態(tài)的邏輯
}
}
// 已發(fā)貨狀態(tài)類
public class ShippedState implements OrderState {
@Override
public void handle() {
System.out.println("當(dāng)前訂單狀態(tài):已發(fā)貨");
// 處理已發(fā)貨狀態(tài)的邏輯
}
}
接下來,我們創(chuàng)建訂單類 Order
,它包含了當(dāng)前訂單狀態(tài)和一些操作方法。
// 訂單類
public class Order {
private OrderState currentState; // 當(dāng)前訂單狀態(tài)
public Order() {
currentState = new PendingPaymentState(); // 默認(rèn)初始狀態(tài)為待支付
}
public void setCurrentState(OrderState state) {
currentState = state;
}
public void request() {
currentState.handle();
}
}
最后,我們可以進(jìn)行測試,模擬訂單在不同狀態(tài)下的行為變化:
public class Main {
public static void main(String[] args) {
Order order = new Order(); // 創(chuàng)建訂單
// 待支付狀態(tài)
order.request();
// 支付訂單,狀態(tài)轉(zhuǎn)換為已支付
order.setCurrentState(new PaidState());
order.request();
// 發(fā)貨,狀態(tài)轉(zhuǎn)換為待發(fā)貨
order.setCurrentState(new ToBeShippedState());
order.request();
// 完成發(fā)貨,狀態(tài)轉(zhuǎn)換為已發(fā)貨
order.setCurrentState(new ShippedState());
order.request();
}
}
運(yùn)行以上代碼,將得到如下輸出:
以上示例演示了訂單狀態(tài)管理的狀態(tài)模式業(yè)務(wù)代碼。通過狀態(tài)模式,我們可以根據(jù)訂單狀態(tài)的變化觸發(fā)不同的行為邏輯,并且可以方便地添加新的訂單狀態(tài),以滿足業(yè)務(wù)需求。
狀態(tài)模式與其他設(shè)計模式的結(jié)合
策略模式與狀態(tài)模式的對比與聯(lián)系
策略模式和狀態(tài)模式都屬于行為型設(shè)計模式,它們都關(guān)注對象在不同的情境下具有不同的行為。雖然它們有相似之處,但在設(shè)計意圖、應(yīng)用場景和實現(xiàn)方式上存在一些差異。
下面是策略模式和狀態(tài)模式的對比與聯(lián)系:
對比:
-
設(shè)計意圖:策略模式旨在通過定義一組算法或策略,并將其封裝成獨立的對象,使得這些算法可以互換使用。狀態(tài)模式旨在讓一個對象在其內(nèi)部狀態(tài)改變時改變其行為,從而實現(xiàn)狀態(tài)之間的轉(zhuǎn)換。
-
關(guān)注點:策略模式主要關(guān)注算法的選擇和封裝,使得具體的策略可以獨立于客戶端進(jìn)行變化。狀態(tài)模式主要關(guān)注對象的狀態(tài)的管理和轉(zhuǎn)換,以及不同狀態(tài)下的行為執(zhí)行。
-
對象角色:策略模式通常包含一個上下文類(Context)和一組策略類(Strategies),客戶端與上下文類進(jìn)行交互。狀態(tài)模式通常包含一個上下文類(Context)和一組狀態(tài)類(States),客戶端與上下文類進(jìn)行交互。
聯(lián)系:
-
行為的封裝:策略模式和狀態(tài)模式都將行為封裝到獨立的對象中,使得行為可以被動態(tài)地變化。
-
對象之間的互動:策略模式和狀態(tài)模式都需要一個上下文類(Context)來與策略對象或狀態(tài)對象進(jìn)行交互,并將具體的行為委托給策略對象或狀態(tài)對象來執(zhí)行。
-
可擴(kuò)展性:策略模式和狀態(tài)模式都具有較好的可擴(kuò)展性。在策略模式中,可以方便地新增、修改或切換不同的策略對象。在狀態(tài)模式中,可以方便地新增、修改或切換不同的狀態(tài)對象。
總的來說,策略模式和狀態(tài)模式都是強(qiáng)調(diào)對象行為的靈活性和可擴(kuò)展性的設(shè)計模式。它們的主要區(qū)別在于策略模式關(guān)注算法的選擇和封裝,而狀態(tài)模式關(guān)注對象狀態(tài)的管理和轉(zhuǎn)換。根據(jù)具體的需求,選擇適合的模式來提高代碼的可維護(hù)性和可擴(kuò)展性。
工廠模式與狀態(tài)模式的結(jié)合實踐
- 結(jié)合工廠模式可以實現(xiàn)狀態(tài)類的動態(tài)創(chuàng)建和切換,增強(qiáng)了狀態(tài)模式的靈活性和可擴(kuò)展性。
結(jié)合工廠模式可以實現(xiàn)狀態(tài)類的動態(tài)創(chuàng)建和切換,從而增強(qiáng)了狀態(tài)模式的靈活性和可擴(kuò)展性。工廠模式可以將狀態(tài)對象的創(chuàng)建和狀態(tài)轉(zhuǎn)換邏輯與客戶端代碼分離,使得系統(tǒng)更加可維護(hù)和可擴(kuò)展。
下面是一個示例,演示了如何結(jié)合工廠模式和狀態(tài)模式來管理訂單的狀態(tài):
首先,定義訂單狀態(tài)接口 OrderState
和具體的訂單狀態(tài)類,與之前的示例相同。
// 訂單狀態(tài)接口
public interface OrderState {
void handle();
}
// 待支付狀態(tài)類
public class PendingPaymentState implements OrderState {
@Override
public void handle() {
System.out.println("當(dāng)前訂單狀態(tài):待支付");
// 處理待支付狀態(tài)的邏輯
}
}
// 已支付狀態(tài)類
public class PaidState implements OrderState {
@Override
public void handle() {
System.out.println("當(dāng)前訂單狀態(tài):已支付");
// 處理已支付狀態(tài)的邏輯
}
}
// 待發(fā)貨狀態(tài)類
public class ToBeShippedState implements OrderState {
@Override
public void handle() {
System.out.println("當(dāng)前訂單狀態(tài):待發(fā)貨");
// 處理待發(fā)貨狀態(tài)的邏輯
}
}
// 已發(fā)貨狀態(tài)類
public class ShippedState implements OrderState {
@Override
public void handle() {
System.out.println("當(dāng)前訂單狀態(tài):已發(fā)貨");
// 處理已發(fā)貨狀態(tài)的邏輯
}
}
然后,創(chuàng)建一個工廠類 OrderStateFactory
,用于動態(tài)創(chuàng)建訂單狀態(tài)對象。在嚴(yán)格意義上這個工廠是一個不支持?jǐn)U充的,但是在這里僅作為一個示例,如果想要真正達(dá)到動態(tài)創(chuàng)建還是需要用到工廠方法,這里只能算是一個簡單工廠。
// 訂單狀態(tài)工廠類
public class OrderStateFactory {
public static OrderState createOrderState(String stateName) {
switch (stateName.toLowerCase()) {
case "pendingpayment":
return new PendingPaymentState();
case "paid":
return new PaidState();
case "tobeshipped":
return new ToBeShippedState();
case "shipped":
return new ShippedState();
default:
throw new IllegalArgumentException("Invalid state name");
}
}
}
接下來,我們可以使用上述的狀態(tài)類和工廠類進(jìn)行訂單狀態(tài)切換的實踐:文章來源:http://www.zghlxwxcb.cn/news/detail-685167.html
public class Main {
public static void main(String[] args) {
Order order = new Order(); // 創(chuàng)建訂單
// 設(shè)置待支付狀態(tài)
order.setCurrentState(OrderStateFactory.createOrderState("PendingPayment"));
order.request();
// 支付訂單,切換到已支付狀態(tài)
order.setCurrentState(OrderStateFactory.createOrderState("Paid"));
order.request();
// 發(fā)貨,切換到待發(fā)貨狀態(tài)
order.setCurrentState(OrderStateFactory.createOrderState("ToBeShipped"));
order.request();
// 完成發(fā)貨,切換到已發(fā)貨狀態(tài)
order.setCurrentState(OrderStateFactory.createOrderState("Shipped"));
order.request();
}
}
通過工廠模式,我們可以根據(jù)狀態(tài)名稱動態(tài)地創(chuàng)建不同的訂單狀態(tài)對象,并將其設(shè)置為上下文類的當(dāng)前狀態(tài)。這樣,如果要新增或修改訂單狀態(tài),只需要修改工廠類的代碼,而不需要修改客戶端的代碼。這增強(qiáng)了狀態(tài)模式的靈活性和可擴(kuò)展性。文章來源地址http://www.zghlxwxcb.cn/news/detail-685167.html
總結(jié)
- 狀態(tài)模式是一種有助于管理對象不同狀態(tài)下行為變化的設(shè)計模式。通過將狀態(tài)和行為封裝在不同狀態(tài)類中,狀態(tài)模式提供了一種結(jié)構(gòu)化的方式來處理狀態(tài)轉(zhuǎn)換和行為委托。它適用于對象擁有多個狀態(tài)且狀態(tài)轉(zhuǎn)換復(fù)雜的場景,并與其他設(shè)計模式如策略模式、工廠模式等相結(jié)合能夠進(jìn)一步擴(kuò)展其功能和靈活性。
到了這里,關(guān)于設(shè)計模式行為型-狀態(tài)模式的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!