设计模式_19 状态模式
19 状态模式
加油,你可以的。(PS:状态模式给我整吐了,阿西吧。我愿称之为最复杂的模式。)
19.1 概念
对有状态的角色,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部发生改变时改变其行为。
例如进程管理中就绪态、阻塞态、运行态之间的切换,阻塞态的进程不能直接切换到运行态。
19.2 结构
环境角色:定义了客户程序需要的接口,维护一个当前状态,并将与状态相关的操作委托给当前状态对象来处理。
抽象状态角色:定义一个接口,用以封装对象中的特定状态所对应的行为。
具体状态角色:实现抽象状态中的行为。
19.3 实现
19.3.1 UML图
19.3.2 代码
state.h:
//State.h
#ifndef _STATE_H_
#define _STATE_H_
#include<iostream>
#include<string>
using namespace std;
class Context;
class State {
protected:
Context* context;
public:
void setContext(Context* context);
virtual void open() = 0;
virtual void close() = 0;
virtual void stop() = 0;
virtual void run() = 0;
};
class OpeningState : public State {
public:
virtual void open();
virtual void close();
virtual void stop();
virtual void run();
};
class ClosingState : public State {
public:
virtual void open();
virtual void close();
virtual void stop();
virtual void run();
};
class StoppingState : public State {
public:
virtual void open();
virtual void close();
virtual void stop();
virtual void run();
};
class RunningState : public State {
public:
virtual void open();
virtual void close();
virtual void stop();
virtual void run();
};
class Context {
private:
State* state;
public:
OpeningState* OPENING_STATE;
ClosingState* CLOSING_STATE;
StoppingState* STOPPING_STATE;
RunningState* RUNNING_STATE;
Context();
State* getState();
void setState(State* state);
void open();
void close();
void stop();
void run();
};
#endif
state.cpp:
//state.cpp
#include"State.h"
void State::setContext(Context* context) {
this->context = context;
}
void OpeningState::open() {
cout << "电梯即将开启" << endl;
}
void OpeningState::close() {
this->context->setState(context->CLOSING_STATE);
this->context->close();
}
void OpeningState::stop() {
cout << "电梯已经停止" << endl;
}
void OpeningState::run() {
cout << "不能执行该操作" << endl;
}
void ClosingState::open() {
this->context->setState(context->OPENING_STATE);
this->context->open();
}
void ClosingState::close() {
cout << "电梯即将关闭" << endl;
}
void ClosingState::stop() {
cout << "电梯已经停止" << endl;
}
void ClosingState::run() {
this->context->setState(context->RUNNING_STATE);
this->context->run();
}
void StoppingState::open() {
this->context->setState(context->OPENING_STATE);
this->context->open();
}
void StoppingState::close() {
cout << "电梯已经关闭" << endl;
}
void StoppingState::stop() {
cout << "电梯即将停止" << endl;
}
void StoppingState::run() {
this->context->setState(context->RUNNING_STATE);
this->context->run();
}
void RunningState::open() {
cout << "不能执行该操作" << endl;
}
void RunningState::close() {
cout << "电梯运行中" << endl;
}
void RunningState::stop() {
this->context->setState(context->STOPPING_STATE);
this->context->stop();
}
void RunningState::run() {
cout << "电梯即将运行" <<endl;
}
Context::Context() {
this->OPENING_STATE = new OpeningState();
this->CLOSING_STATE = new ClosingState();
this->STOPPING_STATE = new StoppingState();
this->RUNNING_STATE = new RunningState();
}
State* Context::getState() {
return this->state;
}
void Context::setState(State* state) {
this->state = state;
this->state->setContext(this);
}
void Context::open() {
state->open();
}
void Context::close() {
state->close();
}
void Context::stop() {
state->stop();
}
void Context::run() {
state->run();
}
main.cpp:
#include"State.h"
int main() {
Context* context = new Context();
context->setState(new OpeningState());
context->close();
context->run();
context->open();
context->stop();
context->open();
return 0;
}
19.3.3 测试结果
19.4 优缺点
19.4.1 优点
将所有与某个状态相关的行为放到一个类中,并且可以方便的增加新状态,只需要改变对象状态即可改变对象行为。
允许状态转换逻辑与状态对象合成一体,而不是一个巨大的条件语句。
19.4.2 缺点
必然会增加系统类和对象的数目。
结构与实现都比较复杂,使用不当会导致程序结构和代码的混乱。
对“开闭原则”的支持不好。
19.5 使用场景
当一个对象的行为取决于它的状态,并且必须在运行时根据状态改变它的行为时。
一个操作中含有庞大的分支结构,并且这些分支决定于状态的对象时。