狀態模式

狀態模式（），是一种行為類型的软件设计模式，它可以讓物件在其内部狀態有變化時，改變其行為。这种模式有點像有限状态机的概念。狀態模式可以被當成成一種策略模式，它能够通過在調用模式介面中所定義的方法来切換策略。

狀態模式在计算机编程中的用途，是基於其內部狀態，將同一物件的各種有不同行為進行封裝。對於物件来说，这是可以在运行时更改其行为的一种更為簡潔方式，它无需诉诸条件语句而从而提高了可维护性。

 概述 
狀態設計模式是《設計模式：可復用物件導向軟體的基礎》所收錄的二十三個模式之一，本書描述了如何解决常見的设计问题。此类问题涵盖了灵活且可重用的面向对象软件的设计，例如易于实现、更改、测试和重用的对象。

狀態模式常用來解決两個主要問題： 

 当对象的内部状态改变时，它的行为也应该改变。
 应独立定义特定于状态的行为。也就是说，添加新状态不应影响现有状态的行为。

在類中為特定狀態直接實作行為是不夠彈性的，因為它將類與特定行為綁定，這將使得在獨立於這個類，不更改这个類的情况下，無法增加新的狀態或改變狀態的行為。因此，此模式描述了兩種解決方案：

 定義單獨的（狀態）物件，為每個狀態封装特定於裝態的行为。亦即，定義一個介面（狀態）以用於執行特定於狀態的行為，並為每種狀態定義一個實現該接口的類。
 類將特定於狀態的行為委託給它的當前戕態物件，而不直接實現特定於狀態的行為。

這使得類與特定於狀態的行為如何實作獨立開來。新的狀態可以通過定義新的狀態類来實現。類可以在運行時，藉由改變當前狀態物件来改變其行為。

 结构 
在随附的统一建模语言（UML）類圖中， Context 類不直接实现特定于状态的行为。相反，Context通过State介面来执行特定于状态的行为（state.handle() ），这使得Context獨立於特定于狀態行為的实现方式。ConcreteStateA和ConcreteStateB類实现State介面，即为每个状态实现（封装）特定于状态的行为。UML序列图說明了运行时互動：

Context对象将特定于状态的行为委托给不同的State对象。首次時，Context调用handle(this)時，這基於了其当前（初始）狀態（ConcreteStateA），此時執行操作並調用 Context.setState(ConcreteStateB)來將當前狀態更改为ConcreteStateB 。下一次時，Context再次调用handle(this)，這基於了其當前状态对象（ConcreteStateB），此時執行操作並将當前狀態更改为ConcreteStateA。

示例
C++
下面是C++例子：
import std;

using std::shared_ptr;

// Abstract State
class FanState {
public:
    virtual void handleButtonPress(class Fan& fan) const = 0;
    virtual ~FanState() = default;
};

// Context
class Fan {
private:
    shared_ptr<FanState> currentState;
public:
    explicit Fan(shared_ptr<FanState> state):
        currentState{state} {}

    void setState(shared_ptr<FanState> state) noexcept {
        currentState = state;
    }

    void pressButton() noexcept {
        currentState->handleButtonPress(*this);
    }
};

// Concrete States
class OffState : public FanState {
public:
    void handleButtonPress(Fan& fan) const override {
        std::println("Fan is OFF -> Switching to LOW speed.");
        fan.setState(std::make_shared<LowSpeedState>());
    }
};

class LowSpeedState : public FanState {
public:
    void handleButtonPress(Fan& fan) const override {
        std::println("Fan is on LOW speed -> Switching to HIGH speed.");
        fan.setState(make_shared<HighSpeedState>());
    }
};

class HighSpeedState : public FanState {
public:
    void handleButtonPress(Fan& fan) const override {
        std::println("Fan is on HIGH speed -> Turning OFF.");
        fan.setState(make_shared<OffState>());
    }
};

int main() {
    Fan fan(std::make_shared<OffState>());

    // Simulate pressing the button several times
    fan.pressButton(); // OFF -> LOW
    fan.pressButton(); // LOW -> HIGH
    fan.pressButton(); // HIGH -> OFF
    fan.pressButton(); // OFF -> LOW

    return 0;
}

Python
下面是Python的例子：
from abc import ABC, abstractmethod

class State(ABC):
    @abstractmethod
    def __call__(self): pass

class ConcreteStateA(State):
    def __call__(self): 
        print("Called ConcreteStateA handle method")

class ConcreteStateB(State):
    def __call__(self): 
        print("Called ConcreteStateB handle method")

class Context():
    def __init__(self, state):
        self.state = state
    def set_state(self, state):
        self.state = state
    def __call__(self):
        self.state()
其执行：
>>> state1 = ConcreteStateA()
>>> context = Context(state1)
>>> context()
Called ConcreteStateA handle method
>>> state2 = ConcreteStateB()
>>> context.set_state(state2)
>>> context()
Called ConcreteStateB handle method

 参考 

Category:带有Java代码示例的条目
Category:软件设计模式