设计模式之☞状态模式(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 的状态的转变而获得了不同的结果。
 

发布了16 篇原创文章 · 获赞 22 · 访问量 983

猜你喜欢

转载自blog.csdn.net/weixin_41882459/article/details/103887557