1. 程式人生 > >【C++設計模式】狀態模式

【C++設計模式】狀態模式

#ifndef __STATE_H__
#define __STATE_H__

#include <iostream>
#include <string>

//狀態模式:允許一個物件在其內部狀態改變時改變它的行為,使物件看起來似乎修改了它的類。

//狀態模式和策略模式比較像,唯一的差別就是狀態模式由內部提供介面給外面來進行狀態的轉換,而策略模式由外部來建立策略例項來呼叫。

//狀態模式中用類表示狀態,併為每一種具體的狀態都定義一個相應的類,這樣可以將複雜的大問題分解為很多小問題分而治之。

//如果不使用狀態模式,當接口裡的方法比較多時,每個方法內部都進行狀態判斷是一件很繁瑣複雜的事情。

//抽象狀態介面
class iState
{
public:
	virtual void Proc() = 0;
};

//具體狀態
class Morning : public iState
{
public:
	virtual void Proc();
};

class Day : public iState
{
public:
	virtual void Proc();
};

class Night : public iState
{
public:
	virtual void Proc();
};


//上下文類,定義客戶端使用的介面並維護一個具體狀態的例項
class StateContext
{
public:
	StateContext();

	virtual ~StateContext();

	void ChangeState(iState * state);

	void SetHour(int hour);

	void Execute();	

private:
	Morning *m_morning;
	Day     *m_day;
	Night   *m_night;
	iState  *m_state;
};

void TestState();


#endif

#include "State.h"


void Morning::Proc()
{
	printf("Now is Morning \n");
}

void Day::Proc()
{
	printf("Now is Day \n");
}

void Night::Proc()
{
	printf("Now is Night \n");
}

StateContext::StateContext()
{
	m_morning = new Morning();
	m_day     = new Day();
	m_night   = new Night();
	m_state   = m_morning;
}

StateContext::~StateContext()
{
	delete m_morning;
	delete m_day;
	delete m_night;
}

void StateContext::ChangeState(iState * state)
{
	m_state = state;
}

void StateContext::SetHour(int hour)
{
	if (hour < 9 && hour > 4)
	{
		this->ChangeState(m_morning);
	}
	else if (hour >= 9 && hour < 18)
	{
		this->ChangeState(m_day);
	}
	else
	{
		this->ChangeState(m_night);
	}
}

void StateContext::Execute()
{
	m_state->Proc();
}

void TestState()
{
	StateContext * sc = new StateContext();

	for (int hour=0; hour<23; hour++)
	{
		sc->SetHour(hour);
		sc->Execute();
	}

	delete sc;
}