目录
[状态模式(State Pattern)](#状态模式(State Pattern))
状态模式(State Pattern)
状态模式是一种行为型设计模式,它允许对象在其内部状态改变时改变其行为。这种模式可以避免在对象中使用大量的条件语句,从而使我们开发的代码更加清晰和易于维护。
状态模式主要包含以下角色:
-
Context (上下文):定义客户感兴趣的接口,并且维护一个ConcreteState 子类的实例,这个实例定义当前状态。
-
State (状态):定义一个接口以封装与Context 的一个特定状态相关的行为。
-
ConcreteState (具体状态):每一个具体状态类实现了State接口。
实际应用
停车收费系统
-- 实现一个停车收费系统,根据停车时间计算费用,不同的时间段有不同的收费标准。
cpp
#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;
}
音乐播放器的播放状态
-- 实现一个音乐播放器,可以在播放、暂停和停止状态之间切换。
cpp
#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;
}
电梯控制系统
-- 实现一个电梯控制系统,电梯有多种状态,如运行状态、停止状态和维护状态。
cpp
#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;
}
总结
状态模式通过将状态转换逻辑从上下文类中抽离出来,使代码更加清晰和易于维护。