亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

詳解state狀態模式及在C++設計模式編程中的使用實例

2020-05-23 14:07:44
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了state狀態模式及在C++設計模式編程中的使用實例,在設計模式中策略用來處理算法變化,而狀態則是透明地處理狀態變化,需要的朋友可以參考下
 

每個人、事物在不同的狀態下會有不同表現(動作),而一個狀態又會在不同的表現下轉移到下一個不同的狀態(State)。最簡單的一個生活中的例子就是:地鐵入口處,如果你放入正確的地鐵票,門就會打開讓你通過。在出口處也是驗票,如果正確你就可以 ok,否則就不讓你通過(如果你動作野蠻,或許會有報警(Alarm),:))。

有限狀態自動機(FSM)也是一個典型的狀態不同,對輸入有不同的響應(狀態轉移)。

通常我們在實現這類系統會使用到很多的 Switch/Case 語句,Case 某種狀態,發生什么動作,Case 另外一種狀態,則發生另外一種狀態。但是這種實現方式至少有以下兩個問題:
當狀態數目不是很多的時候,Switch/Case 可能可以搞定。但是當狀態數目很多的時候(實際系統中也正是如此),維護一大組的 Switch/Case 語句將是一件異常困難并且容易出錯的事情。
狀態邏輯和動作實現沒有分離。在很多的系統實現中,動作的實現代碼直接寫在狀態的邏輯當中。這帶來的后果就是系統的擴展性和維護得不到保證。

狀態模式就是被用來解決上面列出的兩個問題的,在狀態模式中我們將狀態邏輯和動作實現進行分離。當一個操作中要維護大量的 case 分支語句,并且這些分支依賴于對象的狀態。狀態模式將每一個分支都封裝到獨立的類中。

狀態模式典型的結構圖為:

state狀態模式,C++設計模式編程

 

狀態模式的實現
代碼片斷 1:State.h

//state.h#ifndef _STATE_H_#define _STATE_H_class Context; //前置聲明class State{  public:  State();  virtual ~State();  virtual void OperationInterface(Context* ) = 0;  virtual void OperationChangeState(Context*) = 0;  protected:  bool ChangeState(Context* con,State* st);  private:  //bool ChangeState(Context* con,State* st);};class ConcreteStateA:public State{  public:  ConcreteStateA();  virtual ~ConcreteStateA();  virtual void OperationInterface(Context* );  virtual void OperationChangeState(Context*);  protected:  private:};class ConcreteStateB:public State{  public:  ConcreteStateB();  virtual ~ConcreteStateB();  virtual void OperationInterface(Context* );  virtual void OperationChangeState(Context*);  protected:  private:};#endif //~_STATE_H_

代碼片斷 2:State.cpp

//State.cpp#include "State.h"#include "Context.h"#include <iostream>using namespace std;State::State(){}State::~State(){}void State::OperationInterface(Context* con){  cout<<"State::.."<<endl;}bool State::ChangeState(Context* con,State* st){  con->ChangeState(st);  return true;}void State::OperationChangeState(Context* con){}///ConcreteStateA::ConcreteStateA(){}ConcreteStateA::~ConcreteStateA(){}void ConcreteStateA::OperationInterface(Context* con){  cout<<"ConcreteStateA::OperationInterface  ......"<<endl;}void ConcreteStateA::OperationChangeState(Context* con){  OperationInterface(con);  this->ChangeState(con,new ConcreteStateB());}///ConcreteStateB::ConcreteStateB(){}ConcreteStateB::~ConcreteStateB(){}void ConcreteStateB::OperationInterface(Context* con){  cout<<"ConcreteStateB::OperationInterface......"<<endl;}void ConcreteStateB::OperationChangeState(Context* con){  OperationInterface(con);  this->ChangeState(con,new ConcreteStateA());}

代碼片斷 3:Context.h

//context.h#ifndef _CONTEXT_H_#define _CONTEXT_H_class State;/*****/class Context{  public:  Context();  Context(State* state);  ~Context();  void OprationInterface();  void OperationChangState();  protected:  private:  friend class State; //表明在 State 類中可以訪問 Context 類的 private 字段  bool ChangeState(State* state);  private:  State* _state;};#endif //~_CONTEXT_H_

代碼片斷 4:Context.cpp

//context.cpp#include "Context.h"#include "State.h"Context::Context(){}Context::Context(State* state){  this->_state = state;}Context::~Context(){  delete _state;}void Context::OprationInterface(){  _state->OperationInterface(this);}bool Context::ChangeState(State* state){  ///_state->ChangeState(this,state);  this->_state = state;  return true;}void Context::OperationChangState(){  _state->OperationChangeState(this);}

代碼片斷 5:main.cpp

//main.cpp#include "Context.h"#include "State.h"#include <iostream>using namespace std;int main(int argc,char* argv[]){  State* st = new ConcreteStateA();  Context* con = new Context(st);  con->OperationChangState();  con->OperationChangState();  con->OperationChangState();  if (con != NULL)    delete con;  if (st != NULL)    st = NULL;  return 0;}

代碼說明:狀態模式在實現中,有兩個關鍵點:
1.將狀態聲明為 Context 的友元類(friend class),其作用是讓狀態模式訪問 Context的 protected 接口 ChangeSate()。
狀態及其子類中的操作都將 Context*傳入作為參數,其主要目的是狀態類可以通過這個指針調用 Context 中的方法(在本示例代碼中沒有體現)。這也是狀態模式和 Strategy模式的最大區別所在。

2.運行了示例代碼后可以獲得以下的結果:連續 3 次調用了 Context 的 OprationInterface()因為每次調用后狀態都會改變(A-B-A),因此該動作隨著 Context 的狀態的轉變而獲得了不同的結果。


關于State模式的一些需要注意的地方
這個模式使得軟件可以在不同的state下面呈現出完全不同的特征

不同的theme使得相同的元素呈現出不同的特點
不同的state下面相同的操作產生不同的效果
不同的狀態對相同的信息產生不同的處理
這個模式使得操作的state邏輯更加的清楚,省去了無數的state判斷,而state的擴展性和可維護性和執行效率也大幅度的上升。關于state,有如下幾點要注意的地方:

1.所有的state應該被一個類(State Manager Class)管理:

state之間的跳轉和轉換是非常復雜的,有時一些state可能要跳轉的目標state有幾十個,這個時候我們需要一個管理類(State Manager )來統一的管理這些state的切換,例如目標state的初始化和申請跳轉state的結束處理,以及一些state間共享數據的存儲和處理。與其稱這個Manager 為管理類,不如說是一個中間類,它實現了state之間的解隅,使得各個state之間不比知道target state的具體信息,而只要向Manager申請跳轉就可以了。使得各個state的模塊化更好,更加的靈活

2.所有的state都應該從一個state基類繼承:

既然state要教給一個manager來管理,那么自然的,這些state都應該從一個父類繼承下來,這樣manager并不需要知道很多子類的信息,一個最單純的manager只要只要管理一個這樣的基類的指針就可以了。另外,我們還可以統一的把state的一些共有的屬性放在這里

3.state應該實現為一個singleton:

state并不需要總是被申請,這樣可能會造成管理上的混亂,state資源的申請也不應該可以任意進行,事實上,state的申請權限應該只有 Manager才有,并且有且只有一次。在這樣的情況下,state的構造函數似乎應該被聲明為protected or private ,而Manager應該被聲明為state的友元,但是友元被看成是破壞類的封裝性的一種做法,這一點上,我很矛盾,所以在這一條上我只能采取一種漠視的態度。

4.應該做一個state么?這是一個問題:

state可以說是if-else的一種替代品,極端的情況下面state可以讓你的程序中if-else程序塊消失得無影無蹤,但是,這并不是銀彈。state對于狀態可預知的情況下非常有效,但是對于state不可預知,或者相似的state數量太多。過多的state會造成class的粒度過細,程序反而不簡潔。在這樣的情況下,你應該考慮使用if-else程序塊來替代state。

例如:

有這樣的一個程序,它可以生成任意形狀的多邊形,而多邊形的各個節點是可以移動的,問題就來了。

我并不知道用戶將要使用多少個節點的多邊形,因此我無法的創建那么多相應的state來使得這樣一個程序正常工作。state大多數都是確定的,對于不確定的,state似乎無能為力,例如此例

一種解決方法是我利用Manager傳遞給state一個state參數,讓state有機會知道用戶的操作意圖,在這個例子里面是讓state知道用戶打算操作某一個節點,而state根據這個state參數來處理用戶的操作,比如說,state得到的是用戶操作的某一個點的index ,而state只要寫

points[index].moveTo(points[index].getX()+offset_x , points[index].getY()+offset_y);

就可以,從而避免了state過多出現的問題。



發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲精品色婷婷福利天堂| 欧美性受xxxx黑人猛交| 欧美国产日韩免费| 国产99久久精品一区二区永久免费| 亚洲免费一在线| 日韩欧美在线播放| 九九精品视频在线| 国产精品99久久99久久久二8| 色七七影院综合| 91久久久久久久一区二区| 中文字幕日韩免费视频| 国产精品久久久久久久9999| 国产免费一区二区三区在线能观看| 久久91超碰青草是什么| 日韩视频免费在线观看| 亚洲欧美中文在线视频| 国产精品视频yy9099| 国产精品久久久久久五月尺| 中文字幕亚洲无线码在线一区| 久久免费观看视频| 国产精品18久久久久久首页狼| 一本色道久久88亚洲综合88| 91久久综合亚洲鲁鲁五月天| 欧美三级欧美成人高清www| 中文字幕精品久久久久| 日韩大片免费观看视频播放| 91av在线网站| 亚洲一二三在线| 国产精品视频色| 成人免费xxxxx在线观看| 亚洲国产成人一区| 91av在线播放| 国产精品欧美日韩一区二区| 久久99久久99精品免观看粉嫩| 久久成人精品一区二区三区| 伊人伊成久久人综合网站| 一二美女精品欧洲| 欧美视频不卡中文| 色婷婷久久一区二区| 成人网欧美在线视频| 亚洲精品国精品久久99热一| 欧美成人精品影院| 97国产精品人人爽人人做| 国产欧美日韩综合精品| 日韩久久精品成人| 亚洲欧美在线第一页| 2018日韩中文字幕| 97国产精品人人爽人人做| 91精品综合视频| 中文字幕一区电影| 欧美中文字幕在线视频| 亚洲97在线观看| 色综合久久久久久中文网| 亚洲一区亚洲二区| 久久97精品久久久久久久不卡| 欧美人在线视频| 国产精品美女久久| 伊人久久综合97精品| 亚洲一区二区久久久久久久| 欧美一区二区三区……| 国产日韩欧美黄色| www欧美xxxx| 2019中文字幕在线免费观看| 色婷婷久久一区二区| 日韩精品在线免费播放| 91精品久久久久久久久久久久久| 久久久91精品国产一区不卡| 国产欧美日韩中文字幕| 国产美女久久精品香蕉69| 尤物yw午夜国产精品视频明星| 国产精品自拍偷拍| 精品久久久久久久中文字幕| 欧美洲成人男女午夜视频| 亚洲欧美日韩精品久久| 日韩电影在线观看免费| 在线观看亚洲视频| 亚洲欧洲在线视频| 欧美另类极品videosbest最新版本| 91久久久久久久一区二区| 亚洲精品中文字幕有码专区| 91情侣偷在线精品国产| 欧美午夜丰满在线18影院| 久久精品中文字幕免费mv| 精品久久久在线观看| 日韩风俗一区 二区| 欧美亚洲另类在线| 久久久午夜视频| 欧美多人乱p欧美4p久久| 欧美一区二区三区图| 欧美性生交大片免网| 5566日本婷婷色中文字幕97| 日本欧美中文字幕| 国产成人avxxxxx在线看| 国产精品第七影院| 日韩在线观看视频免费| 日韩中文综合网| 国内外成人免费激情在线视频网站| 亚洲已满18点击进入在线看片| 91sao在线观看国产| 九九九久久久久久| 国产精品欧美日韩久久| 色黄久久久久久| 欧美极度另类性三渗透| 在线电影欧美日韩一区二区私密| 91精品国产91久久久久久吃药| 91美女高潮出水| 成人性生交大片免费观看嘿嘿视频| 国产三级精品网站| 奇门遁甲1982国语版免费观看高清| 欧美美最猛性xxxxxx| 不用播放器成人网| 欧美成人剧情片在线观看| 高清一区二区三区四区五区| 亚洲欧美日韩天堂一区二区| 97香蕉久久超级碰碰高清版| 久久777国产线看观看精品| 91精品国产91久久| 亚洲天堂开心观看| 日韩福利视频在线观看| 69久久夜色精品国产7777| 日产日韩在线亚洲欧美| 欧美国产日韩二区| 久久躁日日躁aaaaxxxx| 欧美电影在线观看高清| 热久久免费国产视频| 亚洲白虎美女被爆操| 中文字幕日韩专区| 2019中文字幕全在线观看| 欧美午夜xxx| 欧美成人亚洲成人日韩成人| 国产精品久久久久久久久久新婚| 日本成人精品在线| 国产精品入口日韩视频大尺度| 久久精品久久久久久| 日韩视频永久免费观看| 国产免费一区二区三区在线能观看| 中文字幕av一区二区三区谷原希美| 国产日韩欧美视频在线| 国产成人在线视频| 久久久久久久久久婷婷| 91人人爽人人爽人人精88v| 久久99国产精品自在自在app| 欧美激情精品久久久久久免费印度| 精品久久久91| 日韩av片永久免费网站| 亚洲成人久久久| 91人成网站www| 久久综合九色九九| 国产中文字幕日韩| 欧美性极品xxxx娇小| 欧美成人免费播放| 亚洲人午夜精品| 久久国产精彩视频| 久久综合伊人77777尤物| 欧美激情综合亚洲一二区| 亚洲人成在线观看| 亚洲国产又黄又爽女人高潮的| www.日韩视频| 色悠久久久久综合先锋影音下载| 中文字幕自拍vr一区二区三区| 亚洲天堂第二页| 久久久精品视频在线观看| 亚洲综合一区二区不卡| 国产一区二区三区在线免费观看|