狀態模式(State Pattern) 以PHP為例
狀態模式(State Pattern)是一種行為型設計模式,它允許物件在內部狀態發生變化時改變其行為。這種模式將物件的行為封裝在不同的狀態類別中,使得物件能夠根據當前的狀態選擇不同的行為。
以下是一個使用 PHP 實現狀態模式的重構案例:
// Context(上下文)類別維護著當前狀態物件並委派相關的請求給該狀態物件
class Context {
private $state;
public function __construct(State $state) {
$this->state = $state;
}
public function setState(State $state) {
$this->state = $state;
}
public function request() {
$this->state->handle($this);
}
}
// State(狀態)介面聲明了具體狀態類別應實現的方法
interface State {
public function handle(Context $context): void;
}
// ConcreteStateA(具體狀態A)實現 State 介面並提供具體的行為
class ConcreteStateA implements State {
public function handle(Context $context): void {
echo "ConcreteStateA: Handle\n";
// 狀態轉換
$context->setState(new ConcreteStateB());
}
}
// ConcreteStateB(具體狀態B)實現 State 介面並提供具體的行為
class ConcreteStateB implements State {
public function handle(Context $context): void {
echo "ConcreteStateB: Handle\n";
// 狀態轉換
$context->setState(new ConcreteStateA());
}
}
// 使用範例
$context = new Context(new ConcreteStateA());
$context->request(); // Output: ConcreteStateA: Handle
$context = new Context(new ConcreteStateB());
$context->request(); // Output: ConcreteStateB: Handle
$context = new Context(new ConcreteStateC());
$context->request(); // Output: ConcreteStateA: Handle
在這個例子中,我們首先定義了一個 `Context` 類別,它維護著當前的狀態物件並委派相關的請求給該狀態物件。`Context` 類別擁有一個 `setState` 方法,用於設定當前的狀態物件。當 `request` 方法被呼叫時,該方法會將請求委派給當前狀態物件的 `handle` 方法。
然後,我們定義了一個 `State` 介面,它聲明了具體狀態類別應該實現的方法 `handle`。我們有兩個具體的狀態類別 `ConcreteStateA` 和 `ConcreteStateB`,它們實現了 `State` 介面並提供了具體的行為。在每個具體狀態的 `handle` 方法中,我們執行了相應的行為並將狀態轉換為另一個狀態。
在使用範例中,我們創建了一個 `Context` 物件並設定初始狀態為 `ConcreteStateA`。當我們呼叫 `request` 方法時,該方法會將請求委派給當前狀態物件的 `handle` 方法,並執行相應的行為。在每次呼叫 `request` 方法後,狀態都會根據行為執行的結果進行轉換。
狀態模式允許物件根據不同的內部狀態來改變其行為,並且使得狀態轉換更加靈活和可擴展。這種模式將不同的行為封裝在不同的狀態類別中,使得每個狀態類別都可以獨立地進行修改和擴展。
留言
張貼留言