程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> [設計模式系列]行為型模式之Status模式

[設計模式系列]行為型模式之Status模式

編輯:C++入門知識

概要
本來不准備寫Status模式,因為它跟Strategy模式簡直就是對孿生兄弟,類結構類似,處理方式類似,相像的幾乎沒有多少好說的,後來權衡了下,畢竟這也是GOF單獨提出來的一種模式,而且Status模式跟Stragegy模式的關注點多少還是有些不同的。那麼Status模式到底能做什麼,怎麼做的呢?
程序中經常會涉及到各種狀態,每種狀態下會有不同的處理邏輯,狀態之間能進行切換,切換狀態的同時也需要改變它們的行為,這種情況下我們的程序很容易陷入各種耦合的泥潭,Status模式可以幫助我們解決這類問題,使程序易於擴展,調理清晰。其實Strategy模式封裝的是算法間的切換,而Status模式做的則是狀態間的切換,關注點不同,但思路則是一樣的。Strategy模式可以參考下文:
【設計模式系列】行為型模式之Strategy模式

目的
把各種狀態獨立封裝,而把狀態切換及相應處理隔離出來,使對象在改變內部狀態時也改變對應狀態的行為。

實例
開發一個項目管理系統,項目會經歷各個階段(可以看做各個狀態),這裡假設只考慮4個階段:需求,設計,編碼,測試。處於不同階段時,系統可以輸出不同的項目文檔報告,比如需求階段輸出需求文檔,設計時為設計文檔,編碼時為代碼評審記錄,測試時則是測試文檔。看看基於Status模式會怎麼考慮。
我們把各種階段(狀態)封裝到不同的類,每個狀態類都會有Report方法來處理不同的報告內容,而這些狀態類不會去關心狀態怎麼切換,行為怎麼改變,這些處理會封裝到獨立的Context類,類圖和代碼如下:


[cpp] 
class Status { 
public: 
     virtual void Report() = 0; 
}; 
class RequirementSts : public Status { 
public: 
     virtual void Report() {}; 
}; 
class DesignSts : public Status { 
public: 
     virtual void Report() {}; 
}; 
class CodingSts : public Status { 
public: 
     virtual void Report() {}; 
}; 
class TestingSts : public Status { 
public: 
     virtual void Report() {}; 
}; 
class Context { 
public: 
     Context(Status* sts) { 
          mSts = sts; 
     } 
     void SetStatus(Status* sts) { 
          mSts = sts; 
     } 
     void Report() { 
          mSts->Report(); 
     } 
private: 
     Status* mSts; 
}; 

Client可以這樣去使用:
[cpp] 
Status* require = new RequirementSts(); 
Context* cntxt = new Context(require); 
cntxt ->Report();     // requirement report 
Status* design = new DesignSts(); 
Context* cntxt = new Context(design); 
cntxt ->Report();     // design report 
...... 

可以看出當Context類的狀態發生變化時,對應的行為也會自動變化。當然我們還能更進一步,可以把狀態變化的流程也封裝到Context類中,首先Context類需要包含四種狀態的對象,也就是在構造函數參數中需要傳遞一個狀態組,然後把狀態切換的流程封裝到NextStatus方法,Client可以通過調用NextStatus方法自動切換狀態和行為,代碼如下:
[cpp] 
class Context { 
public: 
     Context(Status** sts, int stsCount) { 
          mSts = sts; 
          mCount = stsCount; 
          mIndex = 0; 
     } 
     void NextStatus() { 
          mIndex++; 
          if (mIndex >= mCount) { 
               mIndex = 0; 
          } 
     } 
     void Report() { 
          mSts[mIndex]->Report(); 
     } 
private: 
     Status** mSts; 
     int mCount; 
     int mIndex; 
}; 
Client的調用:
[cpp] 
Status* sts[4]; 
sts[0] = new RequirementSts(); 
sts[1] = new DesignSts(); 
sts[2] = new CodingSts(); 
sts[3] = new TestingSts(); 
Context* cntxt = new Context(sts); 
cntxt ->Report();     // requirement report 
cntxt->NextStatus(); 
cntxt ->Report();     // design report 
cntxt->NextStatus(); 
cntxt ->Report();     // coding report 
cntxt->NextStatus(); 
cntxt ->Report();     // testing report 
作者:my_business

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved