六栖博、命令模式 責(zé)任鏈模式

命令模式

面向?qū)ο笾行汲瑁粚?shí)例化一個對象,然后填充該對象仇让。再由別的對象調(diào)用該對象典奉。
將一個請求封裝為一個對象,從而使你可用不同的請求對客戶進(jìn)行參數(shù)化丧叽。單個請求封裝成對象以后卫玖,我們就可以對這個請求存儲更多的信息,使請求擁有更多的能力踊淳。

將請求封裝為對象假瞬,那么可以不必為用戶的每一次提交請求都去執(zhí)行,只要當(dāng)前客戶已經(jīng)提交過請求迂尝,那么就忽略或提示消息給用戶笨触。
同時用戶可以撤銷請求(或者可不可以更改請求內(nèi)容?)
然后服務(wù)器將請求排隊雹舀,然后處理芦劣。

實(shí)現(xiàn)

那12306網(wǎng)站來說。
命令可能有很多種说榆,比如訂票命令虚吟,退票命令,改簽命令等等签财,等等亂七八糟的串慰。
如果能一起接收這些命令,那么就需要一個抽象層唱蒸,命令繼承一個基類邦鲫。這樣接收這個基類的指針就可以了。
所以命令類應(yīng)該有兩個。

UML

命令類

封裝請求和處理請求的對象庆捺。并不直接去處理這些請求古今。
所以他實(shí)際的成員函數(shù)都可以的protect,因?yàn)檫@些對象的成員函數(shù)都是有提交這些請求的對象來處理滔以。
這些類都應(yīng)該持有一個處理這些請求的對象捉腥,所以我們在基類中指定有這么一個私有成員,在初始化的時候填充你画。
然后每一個具體的命令類抵碟,都應(yīng)該有自己的一些數(shù)據(jù)成員,比如訂票的時候用戶信息坏匪,票的信息等拟逮,我們存儲在Data這個集合,或者我們自己假設(shè)的一個類型中适滓。

//抽象層
class Commend
{
public:
  virtual void doit()=0;
};

//具體的命令類
class OrderCom:public Commend
{
public:
  OrderCom(Hander *);
  vitrual void doit()
  {
    hander->exc();
  }
private:
  Data data;
  Handler *handler;
}敦迄;

class RefundCom:public Commend
{
//實(shí)現(xiàn),同上
private:
  Handler *handler;
};

命令類與具體執(zhí)行命令的類,應(yīng)該應(yīng)該解耦粒竖。也就是在做中間層颅崩。
這個中間層應(yīng)不應(yīng)該也是個虛類几于,然后具體的子類再執(zhí)行對應(yīng)的命令蕊苗?
這個就要示情況而定了。

因?yàn)檫@里已經(jīng)實(shí)現(xiàn)了解耦沿彭,如果對一個請求處理的對象可以有多個朽砰,那么就有必要做一個抽象層。

handle類執(zhí)行具體處理任務(wù)喉刘。

class Handle
{

}

為了實(shí)現(xiàn)請求的排隊和集中處理瞧柔,我們還需要在做一個對象。用來集中管理這些命令子類睦裳。
說白了造锅,這些命令子類,只是在封裝需要處理的對象廉邑,和處理者哥蔚。它們他們并不進(jìn)行實(shí)際的處理。
這個類蛛蒙,可以繼承Commend也可以不繼承糙箍,這個類持有一個容器他存儲這些Commend,繼承的原因是:這個隊列類也有一個函數(shù)成員exc()用來執(zhí)行容器里面Commend

class Exc
{
public:
  void exc();//挨個執(zhí)行隊列里的命令
  void add();
  void remove();
private:
  vector<Commend *> _list;
};

除去析構(gòu)牵祟,在移除Commend時要一個個遍歷深夯,如果多的話,那就很麻煩了诺苹。

責(zé)任鏈模式

使多個對象都有機(jī)會處理請求咕晋,從而避免了請求的發(fā)送者和接受者之間的耦合關(guān)系雹拄。將這些對象鏈成一條鏈,并沿著這條鏈傳遞該請求/命令,直到有一個對象處理了該請求捡需。

簡單來講办桨,就是可以將一個對象(或者是命令模式中的一個請求),傳遞給一條“鏈”站辉,直到鏈中的某個處理該請求的對象呢撞,處理了個對象,那么就返回饰剥。

實(shí)現(xiàn)

現(xiàn)象一下殊霞,可以這樣做:

能夠傳遞

  1. 要是這個請求可以在一條鏈中傳遞,那么能想到的方法汰蓉,就是將處理這個請求的對象做一個抽象層绷蹲,然后每個實(shí)際的處理類繼承這個抽象層。然后一個儲存這個“鏈”的類顾孽,擁有一個容器祝钢,按照順序存儲處理類的對象。
    2.節(jié)省一個“鏈”類若厚,想list一樣(單向鏈表)拦英,將下一個處理對象存儲在本對象中,如果本對象不能處理該對象测秸,那么就調(diào)用下一個處理對象的處理函數(shù)疤估。

確保一定能夠被處理

調(diào)用處理類的成員函數(shù),先判斷是否能夠處理該對象霎冯,如果不能铃拇,那就。沈撞。慷荔。跳。缠俺。显晶。
也可以在條之前判斷一下_next如果是一個nullptr那么就返回false。這樣的話晋修,可以不用使用終端的那個類吧碾。

  1. 采用第一種容器的方式,那么就遍歷對象墓卦,依次調(diào)用倦春。如果能夠處理就break。同時,在開始處理之前睁本,可以確保容器的尾元素一定能夠和醋里該對象尿庐。
  2. 采用第二種“單向鏈表”方式,那么需要確保最后一個處理類的成員函數(shù)一定能夠處理該請求呢堰,或者就返回一個不能處理抄瑟。

請求需要存儲在處理類中嘛?

采用處理類調(diào)用函數(shù)成員直接處理請求枉疼,那么請求可以不用存儲皮假。

如何添加下一個處理類

可以直接采用函數(shù)成員addNext()的方式。
也可以采用直接在構(gòu)造函數(shù)中初始化骂维。

最后惹资,選取的是“單向鏈表”的方式。

UML

代碼

//處理類的基類
class AbHandler
{
public:
  virtual bool exc(Req * req)=0;
private:
  AbHandler *_next;
};


//處理類航闺,根據(jù)信息判斷是否可以執(zhí)行褪测。
class Exc1Handler:AbHandler
{
public:
  Exc1Handler(AbHandler* handler):_next(handler);
  virtual bool exc(Req * req)
  {
    if(/*判斷req信息和本類的其他數(shù)據(jù)成員是否能夠處理該請求*/)
    {
      //do
      return true;
    }
    return _next->exc(req);
  }
};

//鏈的終端潦刃,確保一定可以執(zhí)行侮措。
class EndHandler:Abhandler
{
//其他不變,構(gòu)造函數(shù)傳入?yún)?shù)為空
public:
  virtual bool exc()
  {
    //提示信息
    return false;
  }
};

使用

int main()
{
  EndHandler *endHandler=new EndHandler;
  Exc1Handler *exc1=new Exc1Handler(endHandler);
  //.....添加其他的乖杠。
  Exc9Handler *exc9=new Exc9Handler(exc8);
  //另外一個請求類分扎。。滑黔。
  Req req;
  exc9->exc(req);
   
}

鏈的終端先創(chuàng)建笆包,然后執(zhí)行的是鏈的開頭环揽。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末略荡,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子歉胶,更是在濱河造成了極大的恐慌汛兜,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,997評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件通今,死亡現(xiàn)場離奇詭異粥谬,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)辫塌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評論 3 392
  • 文/潘曉璐 我一進(jìn)店門漏策,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人臼氨,你說我怎么就攤上這事掺喻。” “怎么了?”我有些...
    開封第一講書人閱讀 163,359評論 0 353
  • 文/不壞的土叔 我叫張陵感耙,是天一觀的道長褂乍。 經(jīng)常有香客問我,道長即硼,這世上最難降的妖魔是什么逃片? 我笑而不...
    開封第一講書人閱讀 58,309評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮只酥,結(jié)果婚禮上褥实,老公的妹妹穿的比我還像新娘。我一直安慰自己裂允,他們只是感情好性锭,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,346評論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著叫胖,像睡著了一般草冈。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上瓮增,一...
    開封第一講書人閱讀 51,258評論 1 300
  • 那天怎棱,我揣著相機(jī)與錄音,去河邊找鬼绷跑。 笑死拳恋,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的砸捏。 我是一名探鬼主播谬运,決...
    沈念sama閱讀 40,122評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼垦藏!你這毒婦竟也來了梆暖?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,970評論 0 275
  • 序言:老撾萬榮一對情侶失蹤掂骏,失蹤者是張志新(化名)和其女友劉穎轰驳,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體弟灼,經(jīng)...
    沈念sama閱讀 45,403評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡级解,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,596評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了田绑。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片勤哗。...
    茶點(diǎn)故事閱讀 39,769評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖掩驱,靈堂內(nèi)的尸體忽然破棺而出芒划,到底是詐尸還是另有隱情豁延,我是刑警寧澤,帶...
    沈念sama閱讀 35,464評論 5 344
  • 正文 年R本政府宣布腊状,位于F島的核電站诱咏,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏缴挖。R本人自食惡果不足惜袋狞,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,075評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望映屋。 院中可真熱鬧苟鸯,春花似錦、人聲如沸棚点。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瘫析。三九已至砌梆,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間贬循,已是汗流浹背咸包。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留杖虾,地道東北人烂瘫。 一個月前我還...
    沈念sama閱讀 47,831評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像奇适,于是被迫代替她去往敵國和親坟比。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,678評論 2 354

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理嚷往,服務(wù)發(fā)現(xiàn)葛账,斷路器,智...
    卡卡羅2017閱讀 134,654評論 18 139
  • 設(shè)計模式匯總 一间影、基礎(chǔ)知識 1. 設(shè)計模式概述 定義:設(shè)計模式(Design Pattern)是一套被反復(fù)使用注竿、多...
    MinoyJet閱讀 3,939評論 1 15
  • 1 場景問題# 1.1 申請聚餐費(fèi)用## 來考慮這樣一個功能:申請聚餐費(fèi)用的管理茄茁。 很多公司都有這樣的福利魂贬,就是項...
    七寸知架構(gòu)閱讀 3,133評論 3 58
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,095評論 25 707
  • 很久了,一直醞釀著寫自己的故事裙顽。但是付燥,等我讀了很多別人的故事,尤其最近真實(shí)的發(fā)生在自己身邊的事情以后愈犹,發(fā)現(xiàn)其...
    嘮叨妹妹閱讀 481評論 0 1