设计模式_19 状态模式(含 UML图 和 C++代码)

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 使用场景

当一个对象的行为取决于它的状态,并且必须在运行时根据状态改变它的行为时。
一个操作中含有庞大的分支结构,并且这些分支决定于状态的对象时。

return 设计模式概述;

返回设计模式概述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值