1. 程式人生 > 其它 >設計模式(8)-狀態模式(關注狀態之間的變化)

設計模式(8)-狀態模式(關注狀態之間的變化)

狀態模式(State Pattern)是設計模式的一種,屬於行為模式。

定義(源於Design Pattern):當一個物件的內在狀態改變時允許改變其行為,這個物件看起來像是改變了其類。

  狀態模式主要解決的是當控制一個物件狀態的條件表示式過於複雜時的情況。把狀態的判斷邏輯轉移到表示不同狀態的一系列類中,可以把複雜的判斷邏輯簡化。

意圖:允許一個物件在其內部狀態改變時改變它的行為

適用場景:

  1.一個物件的行為取決於它的狀態,並且它必須在執行時刻根據狀態改變它的行為。

  2.一個操作中含有龐大的多分支結構,並且這些分支決定於物件的狀態。

類圖結構:

這樣的話讓程式更加面向物件

狀態模式的好處是將與特定狀態相關的行為區域性化,並且將不同的狀態行為分割開來。  目的就是消除龐大的分支語句,狀態模式通過把各種狀態轉移邏輯分佈到state的子類之間,  來減少相互間的依賴。  什麼時候使用?  當一個物件的行為取決於它的狀態,並且它必須在執行時根據狀態改變它的行為時,就可以  考慮狀態模式。

參考程式碼如下:

#ifndef _STATE_H_
#define _STATE_H_
#include <iostream>
#include <string>

using namespace std;

class Work;

class State{
public:
	virtual void writeProgram(Work* work) = 0;
};
//12 before
class ForenoonState : public State{
public:
	void writeProgram(Work* work);
};
//12 ~ 13 middle
class MoonState:public State{
public:
	void writeProgram(Work* work);
};

//12 ~ 13 middle
class AfterMoonState:public State{
public:
	void writeProgram(Work* work);
};

//晚間
class EveningState:public State{
public:
	void writeProgram(Work* work);
};
//休息
class RestState:public State{
public:
	void writeProgram(Work* work);
};
//睡覺
class SleepingState:public State{
public:
	void writeProgram(Work* work);
};

class Work{
private:
	State* m_current;
	int m_hour;
	bool m_finish;
public:
	Work(void):m_current(NULL),m_finish(false),m_hour(0){
		m_current = new ForenoonState();
	}
	int getHour(void){
		return m_hour;
	}
	void setHour(const int hour){
		m_hour = hour;
	}
	bool getIsFinished(void){
		return m_finish;
	}
	void setFinishFlag(const bool bFinished){
		m_finish = bFinished;
	}
	void setState(State* state){
		m_current = state;
	}
	void writeProgram(){
		m_current->writeProgram(this);
	}
};

void ForenoonState::writeProgram(Work* work){
	if(work->getHour()<12){
		cout<<"當前時間:"<<work->getHour()<<"點 上午工作,精神百倍"<<endl;
	}else{
		work->setState(new MoonState());
		work->writeProgram();
	}
}

void MoonState::writeProgram(Work* work){
	if(work->getHour()<13){
		cout<<"當前時間:"<<work->getHour()<<"點 午休,得去吃飯了!"<<endl;
	}else{
		work->setState(new AfterMoonState());
		//work->writeProgram();
	}
}

void AfterMoonState::writeProgram(Work* work){
	if(work->getHour()<17){
		cout<<"當前時間:"<<work->getHour()<<"點 下午狀態還可以,繼續努力!"<<endl;
	}else{
		work->setState(new EveningState());
		work->writeProgram();
	}
}

void EveningState::writeProgram(Work* work){
	if(work->getIsFinished()){
		work->setState(new RestState());
		work->writeProgram();
	}else{
		if(work->getHour()<21){
			cout<<"當前時間:"<<work->getHour()<<"點 加班啊,疲憊之極!"<<endl;
		}else{
			work->setState(new SleepingState());
			work->writeProgram();
		}
	}
}

void RestState::writeProgram(Work* work){
	cout<<"當前時間:"<<work->getHour()<<"點 下班回家了!"<<endl;
}

void SleepingState::writeProgram(Work* work){
	cout<<"當前時間:"<<work->getHour()<<"點 不行了睡著了!"<<endl;
}

#endif

void main(){
	Work* work = new Work();
	work->setHour(9);
	work->writeProgram();
	work->setHour(10);
	work->writeProgram();
	work->setHour(12);
	work->writeProgram();
	work->setHour(13);
	work->writeProgram();
	work->setHour(14);
	work->writeProgram();
	work->setHour(17);
	work->writeProgram();
	
	work->setFinishFlag(false);
	work->writeProgram();
	
	work->setHour(19);
	work->writeProgram();
	work->setHour(21);
	work->writeProgram();
}

對於狀態頻繁變更需要考慮狀態模式。