C++设计模式——状态模式(State)

状态模式

在软件构建过程中,某些对象的状态变化会导致行为也随之变化。允许一个对象在其内部状态改变时改变它的行为,使对象看起来似乎修改了其行为。

enum NetworkState{
    Network_Open,
    Network_Close,
    Network_Connect,
};
class NetworkProcessor{
    NetworkState state;
public:
    void Operation1(){
        if (state == Network_Open){
            //**********
            state = Network_Close;
        }
        else if (state == Network_Close){
            //..........
            state = Network_Connect;
        }
        else if (state == Network_Connect){
            //$$$$$$$$$$
            state = Network_Open;
        }
    }
    public void Operation2(){
        if (state == Network_Open){
            //**********
            state = Network_Connect;
        }
        else if (state == Network_Close){
            //.....
            state = Network_Open;
        }
        else if (state == Network_Connect){
            //$$$$$$$$$$
            state = Network_Close;
        }
    }
    public void Operation3(){
    }
};

从上述代码可看到,每个方法Operation中,对应状态的行为是不一样的,当Operation1中的状态为Network_Open时,执行完一系列操作后,状态变为Network_Close;当Operation1方法中的状态为Network_Open时,执行完一系列操作后,状态变为Network_Connect,这样的写法高度耦合,违背了开闭原则。

#pragma once
#ifndef STATE_H
#define STATE_H
#include<iostream>
using namespace std;

class NetWorkState {
public:
	NetWorkState* pNext;//状态变更统一
	virtual void Operation1() = 0;
	virtual void Operation2() = 0;
	virtual void Operation3() = 0;
	virtual ~NetWorkState() {}
};

class OpenState :public NetWorkState {
public:
	void Operation1() override;
	void Operation2() override;
	void Operation3() override;
};

class CloseState :public NetWorkState {
public:
	void Operation1() override;
	void Operation2() override;
	void Operation3() override;
};

class ConnectState :public NetWorkState {
public:
	void Operation1() override;
	void Operation2() override;
    void Operation3() override;
};

//开状态的方法行为
void OpenState::Operation1() {
	cout << "Open state  excute operation1" << endl;
	pNext = new CloseState();
	cout << "Now state is  close" << endl;
}
void OpenState::Operation2()  {
	cout << "Open state  excute operation2" << endl;
	pNext = new ConnectState();
	cout << "Now state is  connect" << endl;
}
void OpenState::Operation3()  {
	cout << "Open state  excute operation3" << endl;
	pNext = new OpenState();
	cout << "Now state is  open" << endl;
}
//关状态的方法行为
void CloseState::Operation1() {
	cout << "Close state  excute operation1" << endl;
	pNext = new ConnectState();
	cout << "Now state is  connect" << endl;
}
void CloseState::Operation2() {
	cout << "Close state  excute operation2" << endl;
	pNext = new OpenState();
	cout << "Now state is  open" << endl;
}
void CloseState::Operation3() {
	cout << "Close state  excute operation3" << endl;
	pNext = new CloseState();
	cout << "Now state is  close" << endl;
}
//连接状态的方法行为
void ConnectState::Operation1() {
	cout << "Connect state  excute operation1" << endl;
	pNext = new CloseState();
	cout << "Now state is  close" << endl;
}
void ConnectState::Operation2() {
	cout << "Connect state  excute operation2" << endl;
	pNext = new ConnectState();
	cout << "Now state is  connect" << endl;
}
void ConnectState::Operation3() {
	cout << "Connect state  excute operation3" << endl;
	pNext = new OpenState();
	cout << "Now state is  open" << endl;
}
#endif // !STATE_H

定义一个状态抽象基类,子类状态继承自该基类,重写Operation1、Operation2、Operation3方法。

#include<iostream>
#include"state.h"

using namespace std;

class NetWorkProcess {//稳定的,不需要修改
public:
	NetWorkProcess(NetWorkState* state) {
		this->pState = state;
	}
	void Operate1() {
		pState->Operation1();
		pState = pState->pNext;
	}
	void Operate2() {
		pState->Operation2();
		pState = pState->pNext;
	}
	void Operate3() {
		pState->Operation3();
		pState = pState->pNext;
	}
	~NetWorkProcess() {
		delete pState;
	}
private:
	NetWorkState* pState;
};

int main()
{
	NetWorkProcess* networkPro = new NetWorkProcess(new OpenState());
	networkPro->Operate1();
	networkPro->Operate2();
	networkPro->Operate3();
	delete networkPro;
	return 0;
}

只需要在NetWorkProcess中执行各种状态的方法,执行后,切换状态即可。不影响State派生类的前提下在NetworkProcess的方法中执行State类的方法。
运行结果如下:
在这里插入图片描述
为了和strategy进行比较,另一种实现方式如下:

#include<iostream>
using namespace std;

class NetworkProcess;
class NetworkState {
public:
	virtual void Process(NetworkProcess* netPro) = 0;
	virtual ~NetworkState(){}
};
class OpenState :public NetworkState {
public:
	//执行行为并改变状态
	virtual void Process(NetworkProcess* netPro);
};

class CloseState :public NetworkState {
public:
	virtual void Process(NetworkProcess* netPro);
};

class ConnectState :public NetworkState {
public:
	virtual void Process(NetworkProcess* netPro);
};

class NetworkProcess {
public:
	NetworkProcess(NetworkState* state);
	void Request();
	void ChangeState(NetworkState* pState);
private:
	NetworkState* state;
};

void OpenState::Process(NetworkProcess* netPro) {
	cout << "Open State" << endl;
	netPro->ChangeState(new CloseState());
}
void CloseState::Process(NetworkProcess* netPro) {
	cout << "Close State" << endl;
	netPro->ChangeState(new ConnectState());
}
void ConnectState::Process(NetworkProcess* netPro) {
	cout << "Connect State" << endl;
	netPro->ChangeState(new OpenState());
}

NetworkProcess::NetworkProcess(NetworkState* state) {
	this->state = state;
}
void NetworkProcess::Request() {
	if (this->state != nullptr)
		this->state->Process(this);
}
void NetworkProcess::ChangeState(NetworkState* pState) {
	this->state = pState;
}

int main()
{
	NetworkProcess* netPro = new NetworkProcess(new OpenState());
	netPro->Request();
	netPro->Request();
	netPro->Request();
	netPro->Request();
	return 0;
}

结果如下:
在这里插入图片描述

与第一种方式不同的是,在派生状态类的方法中,传入了NetworkProcess对象,使得在执行操作之后,改变状态时调用NetworkProcess中的方法,**State模式很好地实现了对象的状态逻辑和动作实现的分离,状态逻辑分布在State的派生类中实现,而动作实现则可以放在NetworkProcess类中实现。**这使得两者的变化相互独立,改变State的状态逻辑可以很容易复用NetworkProcess的动作。
与strategy不同的是,strategy模式主要是具体算法和实现接口的解耦,而state模式还要考虑状态的切换导致的行为变化。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dailingGuo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值