设计模式之状态模式(思想)

设置模式之状态模式

在这里插入图片描述

上图学过网络的同学应该都比较清楚吧,这是一张TCP状态转换图,只要理解上图,那么对状态模式也就很容易理解啦。

状态模式的意图

​ 允许一个对象在其内部状态改变时改变它的行为。简单的说就是:一个人他的外表没有改变,但是他内在的心里状态发生了改变,那他之后的行为就像变了一个人似的;就好比,一个帅哥在追女神的时候,内心无比激动,“舔狼”本色尽显,这时候他的行为时,说话细声细语,对人关怀备至;然而女神的屌丝男友来了,那这个时候,帅哥内心有起伏变化了,行为变得粗鲁无礼,说话也是粗声粗语;人还是那个人,但是内心的状态变化让他的行为举止变了,当然状态的变化时需要一些触发的,下面我们来看看状态模式的细节吧。

状态模式的动机

​ 一个网络连接的类TCPConnection,这个TCPConnection对象的状态处于若干不同状态之一:连接已建立(Established),正在监听(Listening),连接已关闭(Closed)等等。当一个TCPConnection对象收到其他对象请求时,它会根据当前状态做出不同的反应。

​ 这一模式的关键思想是引入了一个称为TCPState的抽象类来表示网络的连接状态。TCPState类为各表示不同的操作状态的子类声明了一个公共接口。

状态模式的使用场景
  • 一个对象的行为取决于它的状态,它必须在运行时根据状态改变它的行为。
  • 一个操作中含有庞大的多分支条件语句,且这些分支依赖于该对象的状态。
状态模式的结构

在这里插入图片描述

Context(环境,如TCP Connection)

​ 定义用户感兴趣的接口。

​ 维护一个ConcreteState子类的实例,这个实例表示当前状态。

State(状态,如TCPState)

​ 定义一个接口以封装与Context的一个特定状态相关的行为。

ConcreteState subClasses(具体状态类,如TCPEstablished,TCPClosed)

​ 每一个子类实现一个Context的一个状态相关的行为。

示例代码(不可运行)
/* 头文件 */
class TCPState;

class TCPConnection {
public:
	TCPConnection();		/* 构造函数 */

	/* 操作 */
	void ActiveOpen();
	void PassiveOpen();
	void Close();
	void Send();
	void Acknowledge();
	void Synchronize();

	void ProcessOctet(TCPOctetStream*);
private:
	friend class TCPState;			/* 友元类 */
	void ChangeState(TCPState*);
private:
	TCPState* _state;				/* 状态 */
};

/* 状态类,最重要的类,主要是用来表示TCPConnection的状态的类 */
/* 这里的状态转换都是通过具体类内部进行的转换,不需要TCPConnection来维持 */
class TCPState {
public:
	virtual void Transmit(TCPConnection*, TCPOctetStream*);
	virtual void ActiveOpen(TCPConnection*);
	virtual void PassiveOpen(TCPConnection*);
	virtual void Close(TCPConnection*);
	virtual void Synchronize(TCPConnection*);
	virtual void Acknowledge(TCPConnection*);
	virtual void Send(TCPConnection*);
protected:
	void ChangeState(TCPConnection*, TCPState*);
};

class TCPOctetStream {};

/* 具体的状态类 */
class TCPClosed : public TCPState {
public:
	static TCPState* Instance();
	virtual void ActiveOpen(TCPConnection*);
	virtual void PassiveOpen(TCPConnection*);
};

class TCPEStablished : public TCPState {
public:
	static TCPState* instance();
	virtual void Transmit(TCPConnection*, TCPOctetStream*);
	virtual void Close(TCPConnection*);
};

class TCPListen : public TCPState {
public:
	static TCPState* Instance();
	virtual void send(TCPConnection*);
};
/* TCPConnection.cpp */
#include "TCPConnection.h"
#include "TCPClosed.h"
#include "TCPEstablished.h"
#include "TCPListen.h"

#include <iostream>

TCPConnection::TCPConnection() {
	_state = TCPClosed::Instance();
}

void TCPConnection::ChangeState(TCPState* s) {
	_state = s;
}

void TCPConnection::ActiveOpen() {
	_state->ActiveOpen(this);
}

void TCPConnection::PassiveOpen() {
	_state->PassiveOpen(this);
}

void TCPConnection::Close() {
	_state->Close(this);
}

void TCPConnection::Acknowledge() {
	_state->Acknowledge(this);
}

void TCPConnection::Synchronize() {
	_state->Synchronize(this);
}

void TCPConnection::Send() {
	_state->Send(this);
}

void TCPConnection::ProcessOctet(TCPOctetStream* o) {
	std::cout << "processOctet" << std::endl;
}

/* TCPState.cpp */
#include "TCPState.h"

void TCPState::Transmit(TCPConnection*, TCPOctetStream*) {}

void TCPState::ActiveOpen(TCPConnection*) {}
void TCPState::PassiveOpen(TCPConnection*) {}
void TCPState::Close(TCPConnection*) {}
void TCPState::Synchronize(TCPConnection*) {}

void TCPState::ChangeState(TCPConnection* t, TCPState* s) {
	t->ChangeState(s);
}

/* 具体状态类的cpp */
/* 这里的具体实例的Instance()函数都是使用单例模式来实现的 */
void TCPClosed::ActiveOpen(TCPConnection *t){
    ChangeState(t,TCPEstablished::Instance());
}

void TCPClosed::PassiveOpen(TCPConnection* t){
    ChangeState(t,TCPListen::Instance());
}

void TCPEstablished::Close(TCPConnection *t){
    ChangeState(t,TCPCLose::Instance());
}

void TCPEstablished::Transmit(TCPConnection* t, TCPOctetStream* o){
    t->processOctet(o);
}

void TCPListen::Send(TCPConnection *t){
    ChangeState(t,TCPEstablished::Instance());
}

上面代码锁表示的状态转换图:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值