首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

.NET 設計模式實戰:狀態模式 狀態驅動行為變化

     編輯:關於.NET

一、模式簡介

狀態模式:允許物件在內部狀態改變時改變行為,彷彿變更了其類別。

二、適用場景

  • 條件判斷邏輯過於複雜(大量 if/else 判斷狀態)。
  • 物件行為取決於狀態,且需在運行時根據狀態動態變更行為。

將狀態判斷邏輯遷移至代表各狀態的獨立類別,簡化主邏輯。

三、結構與基礎實作

狀態模式 UML 結構圖

  • Context: 維護 ConcreteState 實例定義當前狀態。
  • State (抽象狀態): 定義封裝特定狀態行為的介面。
  • ConcreteStateA/B/C: 具體狀態實作。

代碼

public class Context {
  public State State { get; set; }
  public Context(State s) { State = s; Console.WriteLine($"初始狀態: {s.GetType().Name}"); }
  public void Request() => State.Handle(this);
}
public abstract class State { public abstract void Handle(Context ctx); }
public class ConcreteStateA : State { public override void Handle(Context c) => c.State = new ConcreteStateB(); }
public class ConcreteStateB : State { public override void Handle(Context c) => c.State = new ConcreteStateC(); }
public class ConcreteStateC : State { public override void Handle(Context c) => c.State = new ConcreteStateA(); }

// Client
Context ctx = new Context(new ConcreteStateA());
ctx.Request(); ctx.Request(); ctx.Request(); // A→B→C→A 循環

基礎版執行結果

四、實戰案例:銀行帳戶狀態管理

銀行帳戶狀態轉換圖

三狀態:RedState (透支)、SilverState (新戶)、GoldState (優質)。依餘額自動轉換:

  • Red: 餘額 < -100 或 0~1000 區間
  • Silver: 0~1000
  • Gold: 1000~10000000

核心代碼結構

// Context: Account
class Account {
  private State _state; private string _owner;
  public Account(string owner) { _owner=owner; _state=new SilverState(0,this); }
  public double Balance => _state.Balance;
  public State State { get=>_state; set=>_state=value; }
  public void Deposit(double amt) { _state.Deposit(amt); Log(); }
  public void Withdraw(double amt) { _state.Withdraw(amt); Log(); }
  public void PayInterest() { _state.PayInterest(); Log(); }
  void Log() => Console.WriteLine($"Balance={Balance:C} Status={State.GetType().Name}\n");
}

// Abstract State
abstract class State {
  protected Account account; protected double balance, interest, lowerLimit, upperLimit;
  public Account Account { get=>account; set=>account=value; }
  public double Balance { get=>balance; set=>balance=value; }
  public abstract void Deposit(double amt);
  public abstract void Withdraw(double amt);
  public abstract void PayInterest();
}

// Concrete States: RedState, SilverState, GoldState
// 各自實作 Deposit/Withdraw/PayInterest 並在 StateChangeCheck() 中依餘額切換狀態
// 例: SilverState.StateChangeCheck()
private void StateChangeCheck() {
  if (balance < lowerLimit) account.State = new RedState(this);
  else if (balance > upperLimit) account.State = new GoldState(this);
}

客戶端測試

Account acc = new Account("Jim Johnson");
acc.Deposit(500); acc.Deposit(300); acc.Deposit(550); // 進入 Gold
acc.PayInterest();
acc.Withdraw(2000); acc.Withdraw(1100); // 回落 Silver/Red
Console.ReadKey();

銀行帳戶案例執行結果

五、總結

狀態模式將狀態相關行為封裝於獨立類別,Context 委派給當前狀態物件,消除龐大條件判斷,符合開放封閉原則。適用於狀態轉換邏輯固定但行為差異大的場景。

出處:https://www.cnblogs.com/ywqu

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved