解析C++編程中若何應用設計形式中的狀況形式構造。本站提示廣大學習愛好者:(解析C++編程中若何應用設計形式中的狀況形式構造)文章只能為提供參考,不一定能成為您想要的結果。以下是解析C++編程中若何應用設計形式中的狀況形式構造正文
感化:當一個對象的內涵狀況轉變時許可轉變其行動,這個對象看起來像是轉變了其類。
UML圖以下:
State類,籠統狀況類,界說一個接口以封裝與Context的一個特定狀況相干的行動。
ConcreteState類,詳細狀況,每個子類完成一個與Context的一個狀況相干的行動。
Context類,保護一個ConcreteState子類的實例,這個實例界說以後的狀況。
狀況形式重要處理的是當掌握一個對象狀況轉換的前提表達式過於龐雜時的情形。把狀況的斷定邏輯轉移到表現分歧狀況的一系列類傍邊,可以把龐雜的斷定邏輯簡化。
狀況形式的利益是將與特定狀況相干的行動部分化,而且將分歧狀況的行動朋分開來。
將特定的狀況相干的行動都放入一個對象中,因為一切與狀況相干的代碼都存在於某個ConcreteState中,所以經由過程界說新的子類可以很輕易地增長新的狀況和轉換。
可以清除宏大的前提分支語句。狀況形式經由過程把各類狀況轉移邏輯散布到State的子類之間,來削減互相間的依附。
當一個對象的行動取決於它的狀況,而且它必需在運轉時辰依據狀況轉變它的行動時,便可以斟酌應用狀況形式。
別的假如營業需求某項營業有多個狀況,平日都是一些列舉常量,狀況的變更都是依附年夜量的多分支斷定語句來完成,此時應當斟酌將每種營業狀況界說為一個State的子類。如許這些對象便可以不依附於其他對象兒自力變更了。
實例代碼以下:
State.h#ifndef _STATE_H_
#define _STATE_H_ class Context; class State { public: virtual void Handle(Context* pContext)=0; ~State(); protected: State(); private: }; class ConcreteStateA : public State { public: ConcreteStateA(); ~ConcreteStateA(); virtual void Handle(Context* pContext); protected: private: }; class ConcreteStateB : public State { public: ConcreteStateB(); ~ConcreteStateB(); virtual void Handle(Context* pContext); protected: private: }; class ConcreteStateC : public State { public: ConcreteStateC(); ~ConcreteStateC(); virtual void Handle(Context* pContext); protected: private: }; class Context { public: Context(State* pState); ~Context(); void Request(); void ChangeState(State* pState); protected: private: State* _state; }; #endif
State.cpp
#include "State.h" #include <iostream> using namespace std; State::State() {} State::~State() {} ConcreteStateA::ConcreteStateA() {} ConcreteStateA::~ConcreteStateA() {} //履行該狀況的行動並轉變狀況 void ConcreteStateA::Handle(Context* pContext) { cout << "ConcreteStateA" << endl; pContext->ChangeState(new ConcreteStateB()); } ConcreteStateB::ConcreteStateB() {} ConcreteStateB::~ConcreteStateB() {} //履行該狀況的行動並轉變狀況 void ConcreteStateB::Handle(Context* pContext) { cout << "ConcreteStateB" << endl; pContext->ChangeState(new ConcreteStateC()); } ConcreteStateC::ConcreteStateC() {} ConcreteStateC::~ConcreteStateC() {} //履行該狀況的行動並轉變狀況 void ConcreteStateC::Handle(Context* pContext) { cout << "ConcreteStateC" << endl; pContext->ChangeState(new ConcreteStateA()); } //界說_state的初始狀況 Context::Context(State* pState) { this->_state = pState; } Context::~Context() {} //對要求做處置,並設置下一狀況 void Context::Request() { if(NULL != this->_state) { this->_state->Handle(this); } } //轉變狀況 void Context::ChangeState(State* pState) { this->_state = pState; }
main.cpp
#include "State.h"
int main() { State* pState = new ConcreteStateA(); Context* pContext = new Context(pState); pContext->Request(); pContext->Request(); pContext->Request(); pContext->Request(); pContext->Request(); return 0; }
總結
關於狀況形式,許多情形下和戰略形式看起來極其類似。現實上它們都是為懂得決詳細子類完成籠統接口的完成異構成績而存在的(封裝變更),然則它們的著重各不雷同。而針對算法的異構成績,模板辦法形式經由過程繼續的方法來轉變一部門算法完成(原子操作在分歧詳細子類中可以有分歧完成),戰略形式則經由過程組合的方法來轉變全部算法(可靜態調換),而狀況形式則強調的是針對分歧的狀況對象可以有分歧的呼應。是以狀況形式現實上強調的狀況的概念,而且強調對狀況轉換的邏輯封裝,即對象能夠處於分歧的狀況下,而各個狀況在呼應了該狀況的完成後能夠會靜態轉到另外一個狀況,而這個改變我們不願望 Context 的介入(Context 不用保護這個轉換)。狀況機在編譯道理的 DFA/NDFA 中很罕見,針對一個輸出字符和已有串,DFA/NDFA 能夠會轉換到別的一個狀況。
是以關於狀況形式有以下幾個症結點:
1. 狀況形式會處置算法的分歧,然則加倍存眷的是狀況的轉變。而且關於狀況的改變邏輯普通會放在 State 子類中完成。而關於分歧狀況的處置則可以放在 Context 類中,State 子類保留一個指向 Context 的援用(現實上常常傳遞一個指向 Context 的指針便可,而不用在 State 子類真正保留一個援用),以挪用這些完成。固然放在 State 子類中完成也無可厚非,不外為了凸起重點,應用前一種方法完成更能解釋成績。固然在現實開辟中,完整可以不受這個制約。
2.在詳細完成進程中,對狀況的轉變我們會在 Context 類中完成(由於Context 才有 State 的概念),而在 State 子類中的狀況改變邏輯完成則經由過程挪用這個完成來到達目標。固然為了不讓這個轉變狀況的接口裸露給通俗客戶法式員,我們將 Context 中這個接口聲明為 private,而在將State 類聲明為 Context 的 friend 類,而且將 State 子類中狀況轉變邏輯完成聲明為 Protected,不讓通俗客戶法式員挪用。詳細請參考示例代碼部門。