欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

设计模式之☞状态模式(state模式)------------------行为型模式

程序员文章站 2024-03-24 19:21:22
...

状态模式:

状态模式本质就是状态间的切换的。在状态比较少,不必实现状态逻辑和动作分离,可以考虑使用switch/case代替。

1)当状态数目不是很多的时候,Switch/Case 可能可以搞定。但是当状态数目很多的时 候(实际系统中也正是如此),维护一大组的 Switch/Case 语句将是一件异常困难并且容易出 错的事情。

2)状态逻辑和动作实现没有分离。在很多的系统实现中,动作的实现代码直接写在状 态的逻辑当中。这带来的后果就是系统的扩展性和维护得不到保证。

        State 模式就是被用来解决上面列出的两个问题的,在 State 模式中我们将状态逻辑和动 作实现进行分离。当一个操作中要维护大量的 case 分支语句,并且这些分支依赖于对象的 状态。State 模式将每一个分支都封装到独立的类中。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模式)------------------行为型模式

 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 的状态的转变而获得了不同的结果。