设计模式——16.状态模式

状态模式(State)

在组件构建过程中,当某些对象的状态经常变化时,此时我们需要既对这些对象状态的变化进行管理又维持高层次模块的稳定性,即可以通过“状态变化”类的模式来进行解决。

状态模式(State)简介:

让一个对象的行为随着内部的状态类变化而变化,而该对象外部就像是换了类一样。主要解决当控制一个对象状态转换的条件/表达式过于复杂时,把状态的判断逻辑转移至表示不同状态的一系列状态类中。

状态模式的结构:
State

C++代码

State抽象类以及具体实现类:

//file: State.h
#pragma once

class Context;

///State
class State
{
public:
	State();
	virtual ~State();
	
	virtual void handle(Context *pC);
};

///ConcreteStateA
class ConcreteStateA : public State
{
public:
	static State * Instance();

	virtual ~ConcreteStateA();

	virtual void handle(Context *pC);

private:
	ConcreteStateA();
	static State * m_State;
};


///ConcreteStateB
class ConcreteStateB : public State
{
public:
	static State * Instance();

	virtual ~ConcreteStateB();

	virtual void handle(Context * pC);

private:
	ConcreteStateB();
	static State * m_State;
};
//file: State.cpp
#include "pch.h"
#include "State.h"
#include "Context.h"
#include <iostream>
using namespace std;

///State
State::State() {}

State::~State() {}

void State::handle(Context *pC) {}


///ConcreteStateA
State *ConcreteStateA::m_State = nullptr;

ConcreteStateA::ConcreteStateA() {}

ConcreteStateA::~ConcreteStateA() {}

State * ConcreteStateA::Instance()
{
	if (nullptr == m_State)
		m_State = new ConcreteStateA();
	return m_State;
}

void ConcreteStateA::handle(Context *pC)
{
	cout << "doing something in State A.\n done,change state to B" << endl;
	pC->changeState(ConcreteStateB::Instance());
}


///ConcreteStateB
State * ConcreteStateB::m_State = nullptr;

ConcreteStateB::ConcreteStateB() {}

ConcreteStateB::~ConcreteStateB() {}

State * ConcreteStateB::Instance()
{
	if (nullptr == m_State)
		m_State = new ConcreteStateB();
	return m_State;
}

void ConcreteStateB::handle(Context *pC)
{
	cout << "doing something in State B.\n done,change state to A" << endl;
	pC->changeState(ConcreteStateA::Instance());
}

Context状态拥有者

//file: Context.h
#pragma once
#include "State.h"

class Context
{
public:
	Context(State *pState);
	virtual ~Context();

	void changeState(State *pState);
	void request();

private:
	State * m_State;
};
//file: Context.cpp
#include "pch.h"
#include "Context.h"

Context::Context(State * pState)
{
	m_State = pState;
}

Context::~Context() {}

void Context::changeState(State *pState)
{
	m_State = pState;
}

void Context::request()
{
	m_State->handle(this);
}

客户端代码:

//file: StatePattern.cpp : This file contains the 'main' function. Program execution begins and ends there.
#include "pch.h"
#include <iostream>
#include "State.h"
#include "Context.h"

int main()
{
	Context *context = new Context(ConcreteStateA::Instance());
	context->request();
	context->request();

	delete context;
	return 0;
}

C#代码

State抽象类以及具体实现类:

//抽象状态类State
abstract class State
{
	public abstract void Handle(Context context);
}

//具体状态类
class ConcreteStateA : State
{
	static State m_State;
	public static State Instance
	{
		get
		{
			if (m_State == null)
				m_State = new ConcreteStateA();
			return m_State;
		}
	}
	public override void Handle(Context context)
	{
		context.ChangeState(ConcreteStateB.Instance);
		Console.WriteLine("The state A Switch to the state B .");
	}
}

class ConcreteStateB : State
{
	static State m_State;
	public static State Instance
	{
		get
		{
			if (m_State == null)
				m_State = new ConcreteStateB();
			return m_State;
		}
	}
	public override void Handle(Context context)
	{
		context.ChangeState(ConcreteStateC.Instance);
		Console.WriteLine("The state B Switch to the state C .");
	}
}

class ConcreteStateC : State
{
	static State m_State;
	public static State Instance
	{
		get
		{
			if (m_State == null)
				m_State = new ConcreteStateC();
			return m_State;
		}
	}
	public override void Handle(Context context)
	{
		context.ChangeState(ConcreteStateA.Instance);
		Console.WriteLine("The state C Switch to the state A .");
	}
}
//状态拥有者
class Context
{
	State m_State = null;

	public Context(State state)
	{
		m_State = state;
	}

	public void Request()
	{
		m_State.Handle(this);
	}

	public void ChangeState(State state)
	{
		m_State = state;
	}
}

客户端代码:

class Program
{
	static void Main(string[] args)
	{
		Context c = new Context(ConcreteStateA.Instance);
		
		c.Request();
		
		c.Request();

		c.Request();

		Console.ReadKey();
	}
}

运行实例:

StateRes

REF

书籍:

设计模式与游戏开发、大话设计模式

GitHub:

https://github.com/me115/design_patterns

posted @ 2018-12-23 18:31  SylvanYan  阅读(190)  评论(0编辑  收藏  举报
TOP