状态模式
在软件构建过程中,某些对象的状态变化会导致行为也随之变化。允许一个对象在其内部状态改变时改变它的行为,使对象看起来似乎修改了其行为。
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模式还要考虑状态的切换导致的行为变化。