设计模式之☞状态模式(state模式)------------------行为型模式
状态模式:
状态模式本质就是状态间的切换的。在状态比较少,不必实现状态逻辑和动作分离,可以考虑使用switch/case代替。
1)当状态数目不是很多的时候,Switch/Case 可能可以搞定。但是当状态数目很多的时 候(实际系统中也正是如此),维护一大组的 Switch/Case 语句将是一件异常困难并且容易出 错的事情。
2)状态逻辑和动作实现没有分离。在很多的系统实现中,动作的实现代码直接写在状 态的逻辑当中。这带来的后果就是系统的扩展性和维护得不到保证。
State 模式就是被用来解决上面列出的两个问题的,在 State 模式中我们将状态逻辑和动 作实现进行分离。当一个操作中要维护大量的 case 分支语句,并且这些分支依赖于对象的 状态。State 模式将每一个分支都封装到独立的类中。State 模式典型的结构图为:
State.h
#pragma once
class Context;
class State
{
public:
State();
virtual ~State();
virtual void OperationInterface(Context *) = 0;
virtual void OperationChangeState(Context *) = 0;
protected:
bool changeState(Context* con, State *st);
private:
};
class ConcreteStateA :public State
{
public:
ConcreteStateA();
virtual ~ConcreteStateA();
virtual void OperationInterface(Context*);
virtual void OperationChangeState(Context*);
protected:
private:
};
class ConcreteStateB :public State
{
public:
ConcreteStateB();
virtual ~ConcreteStateB();
virtual void OperationInterface(Context*);
virtual void OperationChangeState(Context*);
protected:
private:
};
State.cpp
#include "pch.h"
#include "State.h"
#include<iostream>
#include"Context.h"
using namespace std;
State::State()
{
}
State::~State()
{
}
void State::OperationInterface(Context* con)
{
cout << "State::..." << endl;
}
void State::OperationChangeState(Context *con)
{
}
bool State::changeState(Context *con, State *st)
{
con->ChangeState(st);
return true;
}
ConcreteStateA::ConcreteStateA()
{
}
ConcreteStateA::~ConcreteStateA()
{
}
void ConcreteStateA::OperationInterface(Context* con)
{
cout << "ConcreteStateA::OperationInterface......." << endl;
}
void ConcreteStateA::OperationChangeState(Context *con)
{
OperationInterface(con);
this->changeState(con, new ConcreteStateB());
}
ConcreteStateB::ConcreteStateB()
{
}
ConcreteStateB::~ConcreteStateB()
{
}
void ConcreteStateB::OperationInterface(Context* con)
{
cout << "ConcreteStateB::OperationInterface......" << endl;
}
void ConcreteStateB::OperationChangeState(Context* con)
{
OperationInterface(con);
this->changeState(con, new ConcreteStateA());
}
Context.h
#pragma once
class State;
class Context
{
public:
Context();
Context(State *state);
~Context();
void OperationInterface();
void OperationChangeState();
protected:
private:
friend class State;
bool ChangeState(State *state);
private:
State* _state;
};
Context.cpp
#include "pch.h"
#include "Context.h"
#include"State.h"
Context::Context()
{
}
Context::~Context()
{
delete _state;
}
Context::Context(State *state)
{
this->_state = state;
}
void Context::OperationInterface()
{
_state->OperationInterface(this);
}
bool Context::ChangeState(State *state)
{
this->_state = state;
return true;
}
void Context::OperationChangeState()
{
_state->OperationChangeState(this);
}
StatePattern.cpp
#include "pch.h"
#include <iostream>
#include"State.h"
#include"Context.h"
int main()
{
State *st = new ConcreteStateA();
Context* con = new Context(st);
con->OperationChangeState();
con->OperationChangeState();
con->OperationChangeState();
con->OperationChangeState();
if (con != NULL)
delete con;
if (st != NULL)
st = NULL;
return 0;
}
运行结果如下:
State 模式在实现中,有两个关键点:
1)将 State 声明为 Context 的友元类(friend class),其作用是让 State 模式访问 Context 的 protected 接口 ChangeSate()。
2)State 及其子类中的操作都将 Context*传入作为参数,其主要目的是 State 类可以通 过这个指针调用 Context 中的方法(在本示例代码中没有体现)。这也是 State 模式和 Strategy 模式的最大区别所在。
运行了示例代码后可以获得以下的结果:连续 4 次调用了 Context 的 OprationInterface() 因为每次调用后状态都会改变(A-B-A-B),因此该动作随着 Context 的状态的转变而获得了不同的结果。
上一篇: Java消息中间件---基础篇
下一篇: opencv学习笔记(二十九)轮廓发现