日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

设计模式的理解:状态模式(State) 和备忘录模式(Memento)

發(fā)布時間:2024/10/14 asp.net 143 豆豆
生活随笔 收集整理的這篇文章主要介紹了 设计模式的理解:状态模式(State) 和备忘录模式(Memento) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、狀態(tài)模式? ?

? 狀態(tài)模式,允許對象在內部狀態(tài)發(fā)生改變時改變它的行為,對象看起來好像修改了它的類。它的實現方式和策略模式相似,目的都是對if...else語句進行優(yōu)化,只不過,策略模式通過外部傳入枚舉、條件來決定選擇哪一種操作方式。策略模式中的枚舉、條件相當于狀態(tài)模式中的狀態(tài)。狀態(tài)不需要由外部傳入,而是隨著自身的操作來自動地變化。

?

?

例如類Context 包含以下的流程圖,context 有兩個方法run 和fallback,四種狀態(tài),例如當狀態(tài)Ready執(zhí)行一次run操作狀態(tài)變成了d式,允許對象在內部狀態(tài)發(fā)生改變時改變它的行為,對象看起來好像修改了它的類。它的實現方式和策略模式相似,目的都是對if...else語句進行優(yōu)化,只不過,策略模式通過外部傳入枚舉、條件來決定選擇哪一種操作方式。策略模式中的枚舉、條件相當于狀態(tài)模式中的狀態(tài)。狀態(tài)不需要由外部傳入,而是隨著自身的操作來自動地變化。

?

?

例如類Context 包含以下的流程圖,context 有兩個方法run 和fallback,四種狀態(tài),例如當狀態(tài)Ready執(zhí)行一次run操作狀態(tài)變成了executing,當再執(zhí)行run時就變成了完成狀態(tài),如果執(zhí)行fallback就變成了hangup狀態(tài)。?

?

本例目標是為了展示?2*100 ?的計算和輸出過程。

方法一

enum State{Ready,Executing,Finish,Hangup }class Context{State state;int result;public:void run(){if(state == Ready){result = 2;state = Executing;}else if(state == Executing){result *=100;state =Finish;}else if(state == Finish){cout<<"result:"<<result;result=0;state =Ready;}else if(state ==Hangup){state = Executing;}}void fallback(){if(state == Ready){state = Ready;result=0;}else if(state == Executing){state =Hangup;}else if(state == Finish){result /=100;state =Executing;}else if(state ==Hangup){state = Ready;result =2;}} }

當操作方法發(fā)生需求變更時,方法一代碼這樣寫影響范圍就會覆蓋整個流程,代碼不易維護,不易擴展。如果增加狀態(tài),那么枚舉要新增,run方法和fallback方法也要跟者新增,代碼會變得越來越臃腫。

方法二:利用狀態(tài)模式,把枚舉變成類對象

enum State{Ready,Executing,Finish,Hangup } /********狀態(tài)類,可用單例模式進行優(yōu)化***********/ class IState{virtual State oprationRun(Context *)=0;virtual State oprationFallback(Context *)=0; }; class ReadyState:public IState{ public:virtual State oprationRun(Context * context){context->result=2;return Executing;}virtual State oprationFallback(Context * context){context->result=0;return Ready;} }; class ExecutingState:public IState{ public:virtual State oprationRun(Context * context){context->result *=100;return Finish;}virtual State oprationFallback(Context * context){return Hangup;} }; class FinishState:public IState{ public:virtual State oprationRun(Context * context){cout<<"result:"<< context->result;context->result =0;return Ready;}virtual State oprationFallback(Context * context){context->result /=100;return Executing;} }; class HangupState:public IState{ public:virtual State oprationRun(Context * context){return Executing;}virtual State oprationFallback(Context * context){context->result=2;return Ready;} };/*********Context自動地完成操作******************/ class Context{State state; //狀態(tài)屬性,這個屬性變化,操作也會動態(tài)地變化IState * iState; //狀態(tài)對象int result; private: void initIState(){switch(state){case Ready: iState =new ReadyState(); break;case Executing:iState =new ExecutingState(); break;case Finish: iState =new FinishState(); break;case Hangup: iState =new HangupState(); break;Default:....ERROR....} }public:Context(){state =Ready;result =0;}void run(){initIState();state =iState->oprationRun(this);}void fallback(){initIState();state =iState->oprationFallback(this);} }

這樣的好處就是當變更狀態(tài)內部操作時,不需要改動Context方法。當新增一個狀態(tài)時,只需要新增一個狀態(tài)類和一個映射就可以,不需要變動其他狀態(tài)方法。這樣編碼結構清晰,誤操作的可能變小,變得更容易維護。

最后調用過程

void main(){Context context; //result =0 ,狀態(tài)為Readycontext.run(); //result =2 ,狀態(tài)從Ready變成Executing;context.run(); //result =200 ,狀態(tài)從Executing變成finish;context.run(); //輸出 200 ,狀態(tài)從finish變成Ready; result =0 }

?



二、備忘錄模式

? ? ? ? ? ?備忘錄模式,在不破壞封裝性的前提下,捕獲對象內部的狀態(tài),并將者著狀態(tài)放在外部進行保存(比如文件,數據庫)。方便以后對象恢復到原先的狀態(tài)。相當于游戲的存檔。

在模式中,具體實現的方式就是新增一個類,用來存儲原先對象重要的屬性。

繼續(xù)按照上述例子,新增備忘錄類和get/set備忘錄方法

enum State{Ready,Executing,Finish,Hangup } /********狀態(tài)類,可用單例模式進行優(yōu)化***********/ class IState{virtual State oprationRun(Context *)=0;virtual State oprationFallback(Context *)=0; }; class ReadyState:public IState{ public:virtual State oprationRun(Context * context){context->result=2;return Executing;}virtual State oprationFallback(Context * context){context->result=0;return Ready;} }; class ExecutingState:public IState{ public:virtual State oprationRun(Context * context){context->result *=100;return Finish;}virtual State oprationFallback(Context * context){return Hangup;} }; class FinishState:public IState{ public:virtual State oprationRun(Context * context){cout<<"result:"<< context->result;context->result =0;return Ready;}virtual State oprationFallback(Context * context){context->result /=100;return Executing;} }; class HangupState:public IState{ public:virtual State oprationRun(Context * context){return Executing;}virtual State oprationFallback(Context * context){context->result=2;return Ready;} };/*********Context自動地完成操作******************/ class Context{State state; //狀態(tài)屬性,這個屬性變化,操作也會動態(tài)地變化IState * iState; //狀態(tài)對象int result; private: void initIState(){switch(state){case Ready: iState =new ReadyState(); break;case Executing:iState =new ExecutingState(); break;case Finish: iState =new FinishState(); break;case Hangup: iState =new HangupState(); break;Default:....ERROR....} }public:Context(){state =Ready;result =0;}void run(){initIState();state =iState->oprationRun(this);}void fallback(){initIState();state =iState->oprationFallback(this);}/****創(chuàng)建存檔和讀取存檔*****/ContextMemento createMemento(){return ContextMemento (state,result);}void setMemento(ContextMemento& cm){state = cm.oldstate;result = cm.oldresult;} }/**********備忘錄對象************/ class ContextMemento{ public: State oldstate; //狀態(tài)屬性,這個屬性變化,操作也會動態(tài)地變化int oldresult;ContextMemento (State s, int r){oldstate= s; oldresult=r;} } void main(){Context context; //result =0 ,狀態(tài)為Readycontext.run(); //result =2 ,狀態(tài)從Ready變成Executing;ContextMemento contextMemento = context.createMemento();context.run(); //result =200 ,狀態(tài)從Executing變成finish;context.setMemento(contextMemento ); //result =2 狀態(tài)為 Executingcontext.run(); //result =200 ,狀態(tài)從Executing變成finish;context.run();//輸出 200 ,狀態(tài)從finish變成Ready; result =0 }

?

備忘錄的目的就是為了存檔,現如今,儲存/讀取對象有更方便的方式。備忘錄模式在如今有些過時。更有效的方式可以替代備忘錄模式,例如對象序列化,對象編碼等。但是備忘錄的思想還是沒變:

1)不破壞原對象的封裝性

2) 獲取原對象重要的屬性,并對這些屬性進行隱藏

?

總結

以上是生活随笔為你收集整理的设计模式的理解:状态模式(State) 和备忘录模式(Memento)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。