目录
状态模式(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); // 免费时间段,费用为0if (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 Aplayer.pause(); // Pausing Song Aplayer.play(); // Resuming Song Aplayer.stop(); // Stopping Song Aplayer.setTrack("Song B");player.play(); // Playing Song Bplayer.stop(); // Stopping Song Bplayer.pause(); // Cannot pause, Song B is not playingreturn 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 maintenanceelevator.goDown(); // The elevator is going down.elevator.stop(); // Stopping the elevator.return 0;
}
总结
状态模式通过将状态转换逻辑从上下文类中抽离出来,使代码更加清晰和易于维护。