设计模式 状态模式(State Pattern)

设计模式 状态模式(State Pattern)

flyfish

灯有开关两个状态。
交通信号灯的状态变化,有三个状态:红灯、绿灯、和黄灯。
电梯有空闲、上升、下降、打开等状态。
这时候就会想到设计模式。

状态模式(State Pattern)是一种行为设计模式,它允许对象在其内部状态改变时改变其行为。这样看起来,对象似乎修改了它的类。状态模式将状态相关的行为分离到独立的状态类中,并通过在不同的状态类之间进行切换,来实现对象行为的动态变化。通过将状态和行为封装在不同的类中,状态模式可以简化对象的行为逻辑,减少条件分支语句,并使得状态转换更加灵活和易于管理。

关键组件

  1. Context(上下文) :维护一个具体的状态实例,这个实例定义了对象当前的状态。

  2. State(状态接口) :定义一个接口,用于封装与上下文的一个特定状态相关的行为。

  3. ConcreteState(具体状态类) :实现状态接口,具体实现状态相关的行为。

一、模拟一个电灯的状态变化

如何使用状态模式来简化对象状态切换逻辑

  1. State 接口 :定义了一个 handleRequest 方法,具体的状态类需要实现这个方法。

  2. 具体状态类OnStateOffState 分别实现了 handleRequest 方法,表示灯的开和关状态。

  3. 上下文类Light 包含一个状态对象,通过 toggle 方法切换灯的状态。

#include <iostream>
#include <memory>

// 状态接口
class State {
public:
    virtual ~State() = default;
    virtual void handleRequest() = 0;
};

// 具体状态:打开状态
class OnState : public State {
public:
    void handleRequest() override {
        std::cout << "The light is already ON." << std::endl;
    }
};

// 具体状态:关闭状态
class OffState : public State {
public:
    void handleRequest() override {
        std::cout << "The light is already OFF." << std::endl;
    }
};

// 上下文:灯
class Light {
private:
    std::shared_ptr<State> state_;

public:
    Light() : state_(std::make_shared<OffState>()) {}

    void setState(std::shared_ptr<State> state) {
        state_ = state;
    }

    void toggle() {
        if (dynamic_cast<OffState*>(state_.get())) {
            std::cout << "Turning light ON." << std::endl;
            setState(std::make_shared<OnState>());
        } else {
            std::cout << "Turning light OFF." << std::endl;
            setState(std::make_shared<OffState>());
        }
        state_->handleRequest();
    }
};

int main() {
    Light light;
    light.toggle();  // Turning light ON.
    light.toggle();  // Turning light OFF.

    return 0;
}

输出

Turning light ON.
The light is already ON.
Turning light OFF.
The light is already OFF.

二、红绿灯状态模式示例

在这个例子中,我们将有三个状态:红灯、绿灯、和黄灯。信号灯会在不同的状态之间切换,每个状态都有一个 show() 方法来表示当前状态,循环展示红灯、绿灯、和黄灯的状态,每个状态持续 3 秒钟

说明

状态类的定义:
每种状态(RedLight、GreenLight、YellowLight)继承自基类 TrafficLightState。
每个状态类实现了 nextState 和 printState 方法,根据当前状态决定下一个状态。

状态转换逻辑:
每个状态类实现了 nextState 方法,用于返回下一个状态的实例。例如,RedLight 的 nextState 方法返回一个新的 GreenLight 实例。

状态变化的封装:
状态的变化对客户端代码(如 simulateTrafficLight 函数)是透明的。客户端代码只需要调用 nextState,而不需要知道具体的状态转换逻辑。

多态性:
通过使用基类指针(或智能指针 std::shared_ptr)来引用具体的状态对象,实现了状态的多态性。这使得可以在运行时动态改变对象的行为。

行为的委托:
对象将其行为委托给其内部状态对象,而不是通过条件语句来显式地管理状态。

代码实现

#include <iostream>
#include <memory>

// 交通灯状态的基类
class TrafficLightState {
public:
    virtual ~TrafficLightState() = default;
    virtual std::shared_ptr<TrafficLightState> nextState() = 0;
    virtual void printState() const = 0;
};

// 前向声明 GreenLight 和 YellowLight 类
class GreenLight;
class YellowLight;

// RedLight 类继承自 TrafficLightState
class RedLight : public TrafficLightState {
public:
    std::shared_ptr<TrafficLightState> nextState() override;
    void printState() const override;
};

// GreenLight 类继承自 TrafficLightState
class GreenLight : public TrafficLightState {
public:
    std::shared_ptr<TrafficLightState> nextState() override;
    void printState() const override;
};

// YellowLight 类继承自 TrafficLightState
class YellowLight : public TrafficLightState {
public:
    std::shared_ptr<TrafficLightState> nextState() override;
    void printState() const override;
};

// RedLight 类的成员函数实现
std::shared_ptr<TrafficLightState> RedLight::nextState() {
    return std::make_shared<GreenLight>();  // 转换到绿灯
}

void RedLight::printState() const {
    std::cout << "Red Light\n";
}

// GreenLight 类的成员函数实现
std::shared_ptr<TrafficLightState> GreenLight::nextState() {
    return std::make_shared<YellowLight>();  // 转换到黄灯
}

void GreenLight::printState() const {
    std::cout << "Green Light\n";
}

// YellowLight 类的成员函数实现
std::shared_ptr<TrafficLightState> YellowLight::nextState() {
    return std::make_shared<RedLight>();  // 转换回红灯
}

void YellowLight::printState() const {
    std::cout << "Yellow Light\n";
}

// 模拟交通灯功能
void simulateTrafficLight(std::shared_ptr<TrafficLightState> state, int steps) {
    for (int i = 0; i < steps; ++i) {
        state->printState();
        state = state->nextState();
    }
}

int main() {
    // 从红灯开始
    std::shared_ptr<TrafficLightState> state = std::make_shared<RedLight>();
    simulateTrafficLight(state, 5);

    return 0;
}

输出

Red Light
Green Light
Yellow Light
Red Light
Green Light

电梯系统可以使用状态模式来实现。

电梯具有多个状态,如“停止”、“上升”、“下降”、“门打开”等。每个状态都有不同的行为和转换条件。使用状态模式可以帮助将这些状态相关的逻辑清晰地组织起来。

关键状态
Idle(空闲状态):电梯处于停止状态,不执行任何动作。
MovingUp(上升状态):电梯正在向上移动。
MovingDown(下降状态):电梯正在向下移动。
DoorOpen(门打开状态):电梯的门处于打开状态。

#include <iostream>
#include <memory>
#include <thread>
#include <chrono>

// 前向声明所有状态类
class IdleState;
class MovingUpState;
class MovingDownState;
class DoorOpenState;

// 状态接口
class ElevatorState {
public:
    virtual ~ElevatorState() = default;
    virtual void handleRequest() = 0;
    virtual std::shared_ptr<ElevatorState> nextState() = 0;
};

// 具体状态:空闲状态
class IdleState : public ElevatorState {
public:
    void handleRequest() override;
    std::shared_ptr<ElevatorState> nextState() override;
};

// 具体状态:上升状态
class MovingUpState : public ElevatorState {
public:
    void handleRequest() override;
    std::shared_ptr<ElevatorState> nextState() override;
};

// 具体状态:下降状态
class MovingDownState : public ElevatorState {
public:
    void handleRequest() override;
    std::shared_ptr<ElevatorState> nextState() override;
};

// 具体状态:门打开状态
class DoorOpenState : public ElevatorState {
public:
    void handleRequest() override;
    std::shared_ptr<ElevatorState> nextState() override;
};

// IdleState 方法定义
void IdleState::handleRequest() {
    std::cout << "Elevator is idle. Waiting for requests..." << std::endl;
}

std::shared_ptr<ElevatorState> IdleState::nextState() {
    std::cout << "Transitioning from IdleState to MovingUpState..." << std::endl;
    // 假设接收到一个向上的请求
    return std::make_shared<MovingUpState>();
}

// MovingUpState 方法定义
void MovingUpState::handleRequest() {
    std::cout << "Elevator is moving up." << std::endl;
}

std::shared_ptr<ElevatorState> MovingUpState::nextState() {
    std::cout << "Transitioning from MovingUpState to DoorOpenState..." << std::endl;
    // 到达目的楼层
    return std::make_shared<DoorOpenState>();
}

// MovingDownState 方法定义
void MovingDownState::handleRequest() {
    std::cout << "Elevator is moving down." << std::endl;
}

std::shared_ptr<ElevatorState> MovingDownState::nextState() {
    std::cout << "Transitioning from MovingDownState to DoorOpenState..." << std::endl;
    // 到达目的楼层
    return std::make_shared<DoorOpenState>();
}

// DoorOpenState 方法定义
void DoorOpenState::handleRequest() {
    std::cout << "Elevator doors are open." << std::endl;
}

std::shared_ptr<ElevatorState> DoorOpenState::nextState() {
    std::cout << "Transitioning from DoorOpenState to IdleState..." << std::endl;
    // 假设关闭门后恢复空闲状态
    return std::make_shared<IdleState>();
}

// 上下文:电梯
class Elevator {
private:
    std::shared_ptr<ElevatorState> state_;

public:
    Elevator() : state_(std::make_shared<IdleState>()) {}

    void changeState() {
        state_->handleRequest();
        std::this_thread::sleep_for(std::chrono::seconds(1)); // 模拟时间延迟
        state_ = state_->nextState();
    }
};

int main() {
    Elevator elevator;
    for (int i = 0; i < 6; ++i) {
        elevator.changeState();
    }
    return 0;
}

输出

Elevator is idle. Waiting for requests...
Transitioning from IdleState to MovingUpState...
Elevator is moving up.
Transitioning from MovingUpState to DoorOpenState...
Elevator doors are open.
Transitioning from DoorOpenState to IdleState...
Elevator is idle. Waiting for requests...
Transitioning from IdleState to MovingUpState...
Elevator is moving up.
Transitioning from MovingUpState to DoorOpenState...
Elevator doors are open.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

西笑生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值