狀態模式(state)c++版本
阿新 • • 發佈:2019-02-20
此為大話設計模式中的狀態模式的c++版本
因為此程式碼中各個類的相互依賴比較嚴重,所以加入了標頭檔案將宣告放置在標頭檔案之中
state.h
/*
* state.h
*
* Created on: Aug 10, 2017
* Author: [email protected]
*/
#ifndef _STATE_H_
#define _STATE_H_
#include <iostream>
#include <string>
class State;
//維護一個concreteState的例項,這個例項定義當前狀態
class Work
{
public :
//因為相互包含的問題實現在移至下方
Work();
void Set_state(State *s);
//時間的設定和獲取函式
void Set_hour(double hour);
double Get_hour();
void Write_program();
void Set_task_finished(bool finish);
bool Get_task_finished();
private:
State *_current;
double _hour = 0;
//任務狀態
bool _finish = false;
};
class State
{
public:
virtual ~State(){}
//定義一個工作介面交給子類實現
virtual void Write_program(Work *w){};
};
class ForenoonState:public State
{
public:
void Write_program(Work *w) override;
};
class NoonState:public State
{
public:
//實現基類的工作函式
void Write_program(Work *w) override ;
};
//下午工作類
class AfternoonState:public State
{
public:
//實現基類的工作函式
void Write_program(Work *w) override;
};
//傍晚工作類
class EveningState:public State
{
public:
//實現基類的工作函式
void Write_program(Work *w) override;
};
//睡眠類
class SleepingState:public State
{
public:
//實現基類的工作函式
void Write_program(Work *w) override;
};
//下班類
class RestState:public State
{
public:
//實現基類的工作函式
void Write_program(Work *w) override;
};
#endif /* _STATE_H_ */
state.cpp
/*
* state.cpp
*
* Created on: Aug 7, 2017
* Author: [email protected]
* 狀態模式
* 允許一個物件在其內部狀態改變時
* 改變它的行為.物件看起來似乎修
* 改了他的類.
*/
#include "state.h"
using namespace std;
void ForenoonState::Write_program(Work *w)
{
//檢查時間是否小於12點
if(w->Get_hour() < 12)
{
cout<<"上午工作時間,精神飽滿!!時間:"<<w->Get_hour()<<endl;
}else
{
//將指標設定為中午工作
w->Set_state(new NoonState());
//繼續呼叫WriteProgram函式檢查時間
w->Write_program();
}
}
void NoonState::Write_program(Work *w)
{
//檢查時間是否小於13點
if(w->Get_hour() < 13)
{
cout<<"中午工作時間,餓了,吃飯!!時間:"<<w->Get_hour()<<endl;
}else
{
//將指標設定為下午工作
w->Set_state(new AfternoonState());
//繼續呼叫WriteProgram函式檢查時間
w->Write_program();
}
}
void AfternoonState::Write_program(Work *w)
{
//檢查時間是否小於17點
if(w->Get_hour() < 17)
{
cout<<"下午工作時間,精神還行!!時間:"<<w->Get_hour()<<endl;
}else
{
//將指標設定為傍晚工作
w->Set_state(new EveningState());
//繼續呼叫WriteProgram函式檢查時間
w->Write_program();
}
}
void EveningState::Write_program(Work *w)
{
//檢查任務是否完成
if(w->Get_task_finished())
{
//如果是下班就轉入下班狀態
w->Set_state(new RestState());
w->Write_program();
}else
{
//檢查時間是否小於21點
if(w->Get_hour() < 21)
{
cout<<"加班中......時間:"<<w->Get_hour()<<endl;
}else
{
//將指標設定為傍晚工作
w->Set_state(new SleepingState());
//繼續呼叫WriteProgram函式檢查時間
w->Write_program();
}
}
}
void SleepingState::Write_program(Work *w)
{
//因為到深夜所以直接輸出吃不消
cout<<"吃不消了,睡著了,時間:"<<w->Get_hour()<<endl;
}
void RestState::Write_program(Work *w)
{
//完成工作的輸出
cout<<"下班回家,時間:"<<w->Get_hour();
}
//work類的建構函式實現
Work::Work()
{
//將上午工作的類的指標賦值給_current指標變數
_current = new ForenoonState();
}
//用於修改_current指標變數
void Work::Set_state(State *s)
{
_current = s;
}
//時間的設定和獲取函式
void Work::Set_hour(double hour)
{
_hour = hour;
}
double Work::Get_hour()
{
return _hour;
}
void Work::Write_program()
{
//用已經在建構函式被賦上ForenoonState類的地址的_current
//呼叫ForenoonState類的Write_program函式
//並且傳入Work類的地址讓其可以繼續呼叫Work類中的其它函式
_current->Write_program(this);
}
void Work::Set_task_finished(bool finish)
{
_finish = finish;
}
bool Work::Get_task_finished()
{
return _finish;
}
int main()
{
//緊急專案
Work *emergencyProjects = new Work();
//上班時間
emergencyProjects->Set_hour(9);
emergencyProjects->Write_program();
emergencyProjects->Set_hour(10);
emergencyProjects->Write_program();
emergencyProjects->Set_hour(11);
emergencyProjects->Write_program();
emergencyProjects->Set_hour(12);
emergencyProjects->Write_program();
emergencyProjects->Set_hour(13);
emergencyProjects->Write_program();
emergencyProjects->Set_hour(14);
emergencyProjects->Write_program();
emergencyProjects->Set_hour(17);
//任務沒有完成
emergencyProjects->Set_task_finished(false);
emergencyProjects->Write_program();
emergencyProjects->Set_hour(19);
emergencyProjects->Write_program();
emergencyProjects->Set_hour(22);
emergencyProjects->Write_program();
//釋放資源
delete emergencyProjects;
return 0;
}
State模式的適用性(摘錄自《設計模式》):
1.一個物件的行為取決於他的狀態,並且它必須在執行時刻根據狀態改變他的行為.
2.一個操作中含有龐大的多分支的條件語句,且這些分支依賴與該物件的狀態.這個狀態常用一個或多個列舉常量表示.State模式將每個條件分支放入一個獨立的類中.這使得你可以根據物件自身的情況將物件的狀態作為一個物件,這以物件可以不依賴與其他物件而獨立變化.
State模式的優點(摘錄自《設計模式》):
1.它將與特定狀態相關的行為區域性化,並且將不同狀態的行為分割開來 State模式將所有與一個特定的狀態熱愛相關的行為都放入一個物件中.因為所有與狀態相關的程式碼都存在於某個State子類中,所以通過定義新的子類可以很容易的增加新的狀態和轉換.
2.它使得狀態轉換顯式化 當一個物件僅以內部資料值來定義當前狀態時,其狀態僅表現為對一些變數的複製,這不夠明確.為不同的狀態引入獨立的物件使得轉換變得更加的明確.而且State物件可以保證context不會發生內部狀態不一致的情況,因為從context角度看狀態轉換是原子的——–只需重新繫結一個變數(即context的State物件變數)而無需為多個變數賦值
3.State物件可以被共享 如果State物件沒有例項變數——-即它們表示的狀態完全以它們的型別來編碼——那麼各context物件可以共享一個State物件.當狀態以這種方式被共享時,它們必然是沒有內部狀態,只有行為的輕量級物件.