C++中的状态模式

59 篇文章 0 订阅
52 篇文章 2 订阅

目录

状态模式(State Pattern)

实际应用

停车收费系统

音乐播放器的播放状态

电梯控制系统

总结


状态模式(State Pattern)

状态模式是一种行为型设计模式,它允许对象在其内部状态改变时改变其行为。这种模式可以避免在对象中使用大量的条件语句,从而使我们开发的代码更加清晰和易于维护。

状态模式主要包含以下角色:
1. Context(上下文):定义客户感兴趣的接口,并且维护一个ConcreteState子类的实例,这个实例定义当前状态。
2. State(状态):定义一个接口以封装与Context的一个特定状态相关的行为。
3. ConcreteState(具体状态):每一个具体状态类实现了State接口。

实际应用

停车收费系统

-- 实现一个停车收费系统,根据停车时间计算费用,不同的时间段有不同的收费标准。

#include <iostream>
#include <memory>

// 上下文类
class ParkingMeter;

// 状态接口类
class ParkingState {
public:
    virtual void enterTime(ParkingMeter* meter, int minutes) = 0;
    virtual void calculateFee(ParkingMeter* meter) = 0;
};

// 上下文类
class ParkingMeter {
private:
    std::unique_ptr<ParkingState> state;
    int totalMinutes;
    double fee;

public:
    ParkingMeter();
    void setState(std::unique_ptr<ParkingState> newState);
    void addTime(int minutes);
    void calculateFee();
    int getTotalMinutes() const;
    void setFee(double newFee);
    double getFee() const;
};

// 具体状态类:免费时间段
class FreeState : public ParkingState {
public:
    void enterTime(ParkingMeter* meter, int minutes) override;
    void calculateFee(ParkingMeter* meter) override;
};

// 具体状态类:收费时间段
class PaidState : public ParkingState {
public:
    void enterTime(ParkingMeter* meter, int minutes) override;
    void calculateFee(ParkingMeter* meter) override;
};

// ParkingMeter方法的实现
ParkingMeter::ParkingMeter() : totalMinutes(0), fee(0.0) {
    state = std::make_unique<FreeState>();
}

void ParkingMeter::setState(std::unique_ptr<ParkingState> newState) {
    state = std::move(newState);
}

void ParkingMeter::addTime(int minutes) {
    state->enterTime(this, minutes);
}

void ParkingMeter::calculateFee() {
    state->calculateFee(this);
}

int ParkingMeter::getTotalMinutes() const {
    return totalMinutes;
}

void ParkingMeter::setFee(double newFee) {
    fee = newFee;
}

double ParkingMeter::getFee() const {
    return fee;
}

// FreeState方法的实现
void FreeState::enterTime(ParkingMeter* meter, int minutes) {
    int newTotalMinutes = meter->getTotalMinutes() + minutes;
    meter->setFee(0.0); // 免费时间段,费用为0

    if (newTotalMinutes > 60) {
        // 超过60分钟,进入收费时间段
        meter->setState(std::make_unique<PaidState>());
        meter->addTime(newTotalMinutes - 60);
    } else {
        // 在免费时间段内
        std::cout << "Time entered: " << minutes << " minutes. Total time: " << newTotalMinutes << " minutes." << std::endl;
    }
}

void FreeState::calculateFee(ParkingMeter* meter) {
    std::cout << "Total parking fee: $" << meter->getFee() << " (Free period)" << std::endl;
}

// PaidState方法的实现
void PaidState::enterTime(ParkingMeter* meter, int minutes) {
    int newTotalMinutes = meter->getTotalMinutes() + minutes;
    meter->setFee(newTotalMinutes * 0.5); // 收费时间段,每分钟0.5美元

    std::cout << "Time entered: " << minutes << " minutes. Total time: " << newTotalMinutes << " minutes." << std::endl;
}

void PaidState::calculateFee(ParkingMeter* meter) {
    std::cout << "Total parking fee: $" << meter->getFee() << " (Paid period)" << std::endl;
}

// 客户端代码
int main() {
    ParkingMeter meter;
    meter.addTime(30); // 免费时间段
    meter.calculateFee();

    meter.addTime(40); // 转入收费时间段
    meter.calculateFee();

    meter.addTime(20); // 收费时间段
    meter.calculateFee();

    return 0;
}

音乐播放器的播放状态

-- 实现一个音乐播放器,可以在播放、暂停和停止状态之间切换。

#include <iostream>
#include <memory>
#include <string>

// 上下文类
class MusicPlayer;

// 状态接口类
class PlayerState {
public:
    virtual void play(MusicPlayer* player) = 0;
    virtual void pause(MusicPlayer* player) = 0;
    virtual void stop(MusicPlayer* player) = 0;
};

// 上下文类
class MusicPlayer {
private:
    std::unique_ptr<PlayerState> state;
    std::string currentTrack;

public:
    MusicPlayer();
    void setState(std::unique_ptr<PlayerState> newState);
    void play();
    void pause();
    void stop();
    void setTrack(const std::string& track);
    std::string getTrack() const;
};

// 具体状态类:播放状态
class PlayingState : public PlayerState {
public:
    void play(MusicPlayer* player) override;
    void pause(MusicPlayer* player) override;
    void stop(MusicPlayer* player) override;
};

// 具体状态类:暂停状态
class PausedState : public PlayerState {
public:
    void play(MusicPlayer* player) override;
    void pause(MusicPlayer* player) override;
    void stop(MusicPlayer* player) override;
};

// 具体状态类:停止状态
class StoppedState : public PlayerState {
public:
    void play(MusicPlayer* player) override;
    void pause(MusicPlayer* player) override;
    void stop(MusicPlayer* player) override;
};

// MusicPlayer方法的实现
MusicPlayer::MusicPlayer() {
    state = std::make_unique<StoppedState>();
}

void MusicPlayer::setState(std::unique_ptr<PlayerState> newState) {
    state = std::move(newState);
}

void MusicPlayer::play() {
    state->play(this);
}

void MusicPlayer::pause() {
    state->pause(this);
}

void MusicPlayer::stop() {
    state->stop(this);
}

void MusicPlayer::setTrack(const std::string& track) {
    currentTrack = track;
}

std::string MusicPlayer::getTrack() const {
    return currentTrack;
}

// PlayingState方法的实现
void PlayingState::play(MusicPlayer* player) {
    std::cout << "Already playing " << player->getTrack() << std::endl;
}

void PlayingState::pause(MusicPlayer* player) {
    std::cout << "Pausing " << player->getTrack() << std::endl;
    player->setState(std::make_unique<PausedState>());
}

void PlayingState::stop(MusicPlayer* player) {
    std::cout << "Stopping " << player->getTrack() << std::endl;
    player->setState(std::make_unique<StoppedState>());
}

// PausedState方法的实现
void PausedState::play(MusicPlayer* player) {
    std::cout << "Resuming " << player->getTrack() << std::endl;
    player->setState(std::make_unique<PlayingState>());
}

void PausedState::pause(MusicPlayer* player) {
    std::cout << "Already paused " << player->getTrack() << std::endl;
}

void PausedState::stop(MusicPlayer* player) {
    std::cout << "Stopping " << player->getTrack() << std::endl;
    player->setState(std::make_unique<StoppedState>());
}

// StoppedState方法的实现
void StoppedState::play(MusicPlayer* player) {
    std::cout << "Playing " << player->getTrack() << std::endl;
    player->setState(std::make_unique<PlayingState>());
}

void StoppedState::pause(MusicPlayer* player) {
    std::cout << "Cannot pause, " << player->getTrack() << " is not playing" << std::endl;
}

void StoppedState::stop(MusicPlayer* player) {
    std::cout << "Already stopped " << player->getTrack() << std::endl;
}

// 客户端代码
int main() {
    MusicPlayer player;
    player.setTrack("Song A");

    player.play(); // Playing Song A
    player.pause(); // Pausing Song A
    player.play(); // Resuming Song A
    player.stop(); // Stopping Song A

    player.setTrack("Song B");
    player.play(); // Playing Song B
    player.stop(); // Stopping Song B
    player.pause(); // Cannot pause, Song B is not playing

    return 0;
}

电梯控制系统

-- 实现一个电梯控制系统,电梯有多种状态,如运行状态、停止状态和维护状态。

#include <iostream>
#include <memory>
#include <string>

// 上下文类
class Elevator;

// 状态接口类
class ElevatorState {
public:
    virtual void goUp(Elevator* elevator) = 0;
    virtual void goDown(Elevator* elevator) = 0;
    virtual void stop(Elevator* elevator) = 0;
    virtual void maintain(Elevator* elevator) = 0;
};

// 上下文类
class Elevator {
private:
    std::unique_ptr<ElevatorState> state;

public:
    Elevator();
    void setState(std::unique_ptr<ElevatorState> newState);
    void goUp();
    void goDown();
    void stop();
    void maintain();
};

// 具体状态类:运行状态
class RunningState : public ElevatorState {
public:
    void goUp(Elevator* elevator) override;
    void goDown(Elevator* elevator) override;
    void stop(Elevator* elevator) override;
    void maintain(Elevator* elevator) override;
};

// 具体状态类:停止状态
class StoppedState : public ElevatorState {
public:
    void goUp(Elevator* elevator) override;
    void goDown(Elevator* elevator) override;
    void stop(Elevator* elevator) override;
    void maintain(Elevator* elevator) override;
};

// 具体状态类:维护状态
class MaintenanceState : public ElevatorState {
public:
    void goUp(Elevator* elevator) override;
    void goDown(Elevator* elevator) override;
    void stop(Elevator* elevator) override;
    void maintain(Elevator* elevator) override;
};

// Elevator方法的实现
Elevator::Elevator() {
    state = std::make_unique<StoppedState>();
}

void Elevator::setState(std::unique_ptr<ElevatorState> newState) {
    state = std::move(newState);
}

void Elevator::goUp() {
    state->goUp(this);
}

void Elevator::goDown() {
    state->goDown(this);
}

void Elevator::stop() {
    state->stop(this);
}

void Elevator::maintain() {
    state->maintain(this);
}

// RunningState方法的实现
void RunningState::goUp(Elevator* elevator) {
    std::cout << "The elevator is already running upward." << std::endl;
}

void RunningState::goDown(Elevator* elevator) {
    std::cout << "The elevator is already running downward." << std::endl;
}

void RunningState::stop(Elevator* elevator) {
    std::cout << "Stopping the elevator." << std::endl;
    elevator->setState(std::make_unique<StoppedState>());
}

void RunningState::maintain(Elevator* elevator) {
    std::cout << "Cannot enter maintenance mode while running." << std::endl;
}

// StoppedState方法的实现
void StoppedState::goUp(Elevator* elevator) {
    std::cout << "The elevator is going up." << std::endl;
    elevator->setState(std::make_unique<RunningState>());
}

void StoppedState::goDown(Elevator* elevator) {
    std::cout << "The elevator is going down." << std::endl;
    elevator->setState(std::make_unique<RunningState>());
}

void StoppedState::stop(Elevator* elevator) {
    std::cout << "The elevator is already stopped." << std::endl;
}

void StoppedState::maintain(Elevator* elevator) {
    std::cout << "Entering maintenance mode." << std::endl;
    elevator->setState(std::make_unique<MaintenanceState>());
}

// MaintenanceState方法的实现
void MaintenanceState::goUp(Elevator* elevator) {
    std::cout << "Cannot go up while in maintenance mode." << std::endl;
}

void MaintenanceState::goDown(Elevator* elevator) {
    std::cout << "Cannot go down while in maintenance mode." << std::endl;
}

void MaintenanceState::stop(Elevator* elevator) {
    std::cout << "Cannot stop while in maintenance mode." << std::endl;
}

void MaintenanceState::maintain(Elevator* elevator) {
    std::cout << "Already in maintenance mode." << std::endl;
}

// 客户端代码
int main() {
    Elevator elevator;

    elevator.goUp(); // The elevator is going up.
    elevator.stop(); // Stopping the elevator.
    elevator.maintain(); // Entering maintenance mode.
    elevator.goUp(); // Cannot go up while in maintenance mode.
    elevator.stop(); // Cannot stop while in maintenance mode.

    elevator.setState(std::make_unique<StoppedState>()); // Simulate exiting maintenance
    elevator.goDown(); // The elevator is going down.
    elevator.stop(); // Stopping the elevator.

    return 0;
}

总结

状态模式通过将状态转换逻辑从上下文类中抽离出来,使代码更加清晰和易于维护。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

沉夢志昂丶

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

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

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

打赏作者

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

抵扣说明:

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

余额充值