一 作用
状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。
二 UML类图
三 举个栗子
//state.h
#pragma once
#include <iostream>
#include "live.h"
class Live;
class State {
public:
virtual ~State() = default;
virtual void handle(Live*) = 0;
};
class Live {
public:
Live() = default;
~Live() {
if (state_ptr_) {
delete state_ptr_;
state_ptr_ = nullptr;
}
}
void set_hour(const double& hour) {
hour_ = hour;
}
double get_hour() const {
return hour_;
}
void set_state(State* state) {
if (state_ptr_) {
delete state_ptr_;
state_ptr_ = nullptr;
}
state_ptr_ = state;
}
void current_state() {
state_ptr_->handle(this);
}
private:
double hour_ = 0;
State* state_ptr_ = nullptr;
};
class EveningState : public State
{
public:
void handle(Live* live_ptr) override {
if (live_ptr->get_hour() <= 24) {
std::cout << "Play games in the evening.\n";
}
}
};
class AfterNoonState :public State {
public:
void handle(Live* live_ptr) override {
if (live_ptr->get_hour() <= 18) {
std::cout << "Work in the afternoon.\n";
}
else {
live_ptr->set_state(new EveningState());
live_ptr->current_state();
}
}
};
class NoonState : public State {
public:
void handle(Live* live_ptr) override {
if (live_ptr->get_hour() <= 12) {
std::cout << "Work in the forenoon.\n";
}
else {
live_ptr->set_state(new AfterNoonState());
live_ptr->current_state();
}
}
};
class NightState : public State
{
public:
void handle(Live* live_ptr) override {
if (live_ptr->get_hour() <= 7) {
std::cout << "Sleep at night.\n";
}
else {
live_ptr->set_state(new NoonState());
live_ptr->current_state();
}
}
};
class ErrorState : public State {
public:
void handle(Live* live_ptr) override {
if (live_ptr->get_hour() < 0 ||
live_ptr->get_hour() >24) {
std::cout << "Error state.\n";
}
else {
live_ptr->set_state(new NightState());
live_ptr->current_state();
}
}
};
//main.cpp
#include "state.h"
int main(int argc, char* argv[]) {
std::shared_ptr<Live> live_ptr = std::make_shared<Live>();
for (int i = 25; i > -2; i--) {
live_ptr->set_state(new ErrorState());
live_ptr->set_hour(static_cast<double>(i));
live_ptr->current_state();
}
return 0;
}