C++設計模式10--命令模式(一)--降低請求傳送者與接收者耦合
命令模式概述
在軟體系統中,“行為請求者”與“行為實現者”通常呈現一種“緊耦合”。但在某些場合,比如要對行為進行“記錄、撤銷/重做、事務”等處理,這種無法抵禦變化的緊耦合是不合適的。在這種情況下,如何將“行為請求者”與“行為實現者”解耦?將一組行為抽象為物件,實現二者之間的鬆耦合。這就是命令模式(Command Pattern)
工作了一天感覺好累,洗了個澡,開啟電視看看有沒有喜歡的節目,拿起遙控器,看著上面的按鈕,忽然感覺好奇妙,我們按一開機鍵,電視就開了,然後...哈哈,真好玩,我按我按。細想之下這不就是一個命令模式麼。
命令模式結構
Command
定義命令的介面,宣告執行的方法。
ConcreteCommand
命令介面實現物件,是“虛”的實現;通常會持有接收者,並呼叫接收者的功能來完成命令要執行的操作。
Receiver
接收者,真正執行命令的物件。任何類都可能成為一個接收者,只要它能夠實現命令要求實現的相應功能。
Invoker
要求命令物件執行請求,通常會持有命令物件,可以持有很多的命令物件。這個是客戶端真正觸發命令並要求命令執行相應操作的地方,也就是說相當於使用命令物件的入口。
Client
建立具體的命令物件,並且設定命令物件的接收者。注意這個不是我們常規意義上的客戶端,而是在組裝命令物件和接收者,或許,把這個Client稱為裝配者會更好理解,因為真正使用命令的客戶端是從Invoker來觸發執行。
運作方式
①Client在C/C++中是主函式或者成員函式,它建立一個ConcreteCommand物件並指定他的Receiver物件②某個Invoker物件儲存該ConcreteCommand物件
③該Invoker通過呼叫Command物件的Execute操作來提交一個請求。若該命令是可撤銷的,ConcreteCommand就在執行Execute操作之前儲存當前狀態以用於取消該命令
④ConcreteCommand物件對呼叫它的Receiver的一些操作以執行該請求。
基本程式碼
看看命令接受者
命令接受者才是命令真正的執行者
// 命令的接受者,是真正執行命令的物件 class Receiver { public : virtual void Action() { std::cout <<"do something..." <<endl; } };
再看看命令介面
命令介面的實現物件,執行一個命令,
通常會持有接收者,並呼叫接收者的功能來完成命令要執行的操作。
// 命令的介面
class Command
{
public :
virtual void Execute( ) = 0; // 定義了一個執行的方法
};
// 命令介面的實現物件,執行一個命令,
// 通常會持有接收者,並呼叫接收者的功能來完成命令要執行的操作。
class ConcreteCommand : public Command
{
public :
ConcreteCommand(Receiver *receiver)
{
this->receiver = receiver;
}
void Execute()
{
//通常會轉調接收者物件的相應方法,讓接收者來真正執行功能
receiver->Action();
}
protected:
Receiver *receiver; // 內含一個命令接收者
};
接著看看請求傳送者
要求命令物件執行請求,
通常會持有命令物件,可以持有很多的命令物件
// 要求命令物件執行請求,
// 通常會持有命令物件,可以持有很多的命令物件
class Invoker
{
public :
void SetCommand(Command *command)
{
this->command = command;
}
void RunCommand()
{
command->Execute();
}
protected:
Command *command;
};
最後是客戶端,也就是主程式
int main( )
{
//建立接收者
Receiver *receiver = new Receiver;
//建立命令物件,設定它的接收者
Command *command = new ConcreteCommand(receiver);
//建立Invoker,把命令物件設定進去
Invoker *invoker = new Invoker;
invoker->SetCommand(command); // invoker發出command命令
invoker->RunCommand( ); // 然後去執行這個命令
}
好了我們在這裡只是簡單講講,命令模式的基礎概念,以及基本程式碼實現。下一篇我們將用具體例子實現一下,方便大家理解相關推薦
C++設計模式10--命令模式(一)--降低請求傳送者與接收者耦合
命令模式概述 在軟體系統中,“行為請求者”與“行為實現者”通常呈現一種“緊耦合”。但在某些場合,比如要對行為進行“記錄、撤銷/重做、事務”等處理,這種無法抵禦變化的緊耦合是不合適的。在這種情況下,如何
C++設計模式10--命令模式(二)(Command)--降低請求傳送者與接收者耦合
工作了一天感覺好累,洗了個澡,開啟電視看看有沒有喜歡的節目,拿起遙控器,看著上面的按鈕,忽然感覺好奇妙,我們按一開機鍵,電視就開了,然後...哈哈,真好玩,我按我按。細想之下這不就是一個命令模式麼。 電視機是請求的接收者Receiver, 遙控器是請求的傳送者Concr
請求傳送者與接收者解耦——命令模式(一)
裝修新房的最後幾道工序之一是安裝插座和開關,通過開關可以控制一些電器的開啟和關閉,例如電燈或者排氣扇。在購買開關時,我們並不知道它將來到底用於控制什麼電器,也就是說,開關與電燈、排氣扇並無直接關係,
請求傳送者與接收者解耦——命令模式(三)
4 命令佇列的實現 有時候我們需要將多個請求排隊,當一個請求傳送者傳送一個請求時,將不止一個請求接收者產生響應,這些請求接收者將逐個執行業務方法,完成對請求的處理。此時,我們可以通過命令佇列
請求傳送者與接收者解耦——命令模式(六)
Sunny軟體公司欲開發一個基於Windows平臺的公告板系統。該系統提供了一個主選單(Menu),在主選單中包含了一些選單項(MenuItem),可以通過Menu類的addMenuItem()方法增加選單項。選單項的主要方法是click(),每一個選單項包含一個抽象命令類,具體命令類包括OpenComman
請求傳送者與接收者解耦——命令模式(四)
5 撤銷操作的實現 在命令模式中,我們可以通過呼叫一個命令物件的execute()方法來實現對請求的處理,如果需要撤銷(Undo)請求,可通過在命令類中增加一個逆向操作來實現。 擴充套件 除了通過一個逆向操作來實現撤銷(Undo)外,還可以通
請求傳送者與接收者解耦——命令模式(二)
3 完整解決方案 為了降低功能鍵與功能處理類之間的耦合度,讓使用者可以自定義每一個功能鍵的功能,Sunny軟體公司開發人員使用命令模式來設計“自定義功能鍵”模組,其核心結構如圖4所示:圖4 自定義功能鍵核心結構圖 在圖4中,FBSettingWindo
設計模式之問題集錦(一)
是把 後繼 ogr data- 跟著 沒有 解釋器 space 基本實現 設計模式的主要資料是《大話設計模式》。第一階段先看看各種模式的基本概念。實現每一個模式下的樣例。然後在進行理解性的學習和掌握,靈活掌握各種模式的長處,知道某種模式適合那種狀態。如今,樣
設計模式六大原則例子(一)-- 介面隔離原則(ISP)例子
之前我們對設計模式的六大原則做了簡單歸納,這篇部落格是對介面隔離原則進行的舉例說明。 1介面隔離原則的意義 建立單一介面,不要建立龐大臃腫的介面,儘量細化介面,介面中的方法儘量少。也就是說,我們要為各個類建立專用的介面,而不要試圖去建立一個很龐大的介面供所有依賴它的類去呼叫。 在程式設計中,依賴幾個
Java設計模式之總體簡介(一)——簡單易懂
設計模式(Design pattern)是一套被反覆使用、多數人知曉的、經過分類編目的、程式碼設計經驗的總結。使用設計模式是為了可重用程式碼、讓程式碼更容易被他人理解、保證程式碼可靠性。 毫無疑問,設計模式於己於他人於系統都是多贏的,設計模式使程式碼編制真正工程化,設計模式是
《設計模式——java版》(一)
一、設計模式簡介 1. 設計模式是一套被反覆使用、多數人知曉、經過分類編目的優秀程式碼設計經驗的總結。使用設計模式是為了重用程式碼,使程式碼更容易理解並保證程式碼的可靠性。 &
Koffee設計模式學習之路(一) —— 模式學習總結思路
這篇部落格沒有相關技術細節,僅作為自己對設計模式這個東西的一點感悟和以後設計模式系列部落格的一個寫作思路。 作為非科班出身,誤打誤撞進入程式設計的人,在上研究生期間對於程式的唯一要求就是:能用。彼時,不知道有面向物件,記憶體管理,多執行緒,
Javascript設計模式之簡單工廠(一)
建立型設計模式-簡單工廠模式 簡單工廠模式(Simple Factory):又稱之為靜態工廠模式,由一個工廠物件建立某一種產品物件類的例項。主要用來建立同一類物件。 多類單例項法 為了加深我們的理解,設定以下需求。假設一個大型超市賣各種東西,
基本設計模式學習筆記:(一)常見的七種面向物件設計原則
0.概述 面向物件設計原則為支援可維護性複用而誕生,這些原則蘊含在很多設計模式中,他們是從許多設計方案中總結出來的指導性原則1.單一原則 一個類只負責一個功能領域中的相應職責,或者說:就一個類而言,應該只有一個引起它變化的原因。個人總結:將不同職責的方法放在
從零開始構建一個Reactor模式的網路庫(一) 執行緒同步Mutex和Condition
最近在學習陳碩大神的muduo庫,感覺寫的很專業,以及有一些比較“高階”的技巧和設計方式,自己寫會比較困難。 於是打算自己寫一個簡化版本的Reactor模式網路庫,就取名叫mini吧,同樣只基於Linux平臺,不使用boost庫,去掉一些比較複雜的部分,只實現比較基本的功能。 寫作的過程中,參考了http
RabbitMQ入門及常用的5種模式的簡單使用(一)
RabbitMQ是一個非常常用也非常強大的訊息中介軟體,主要用於應用與應用之間的通訊,有五種常見的使用方式,分別是:簡單模式,工作模式,釋出訂閱模式,路由模式以及萬用字元模式,這裡主要是簡單模式和工作模式!package cn.itcast.rabbitmq.simple;i
【模式識別】模式識別的概述(一)
本節主要內容: 模式和模式識別的概念模式識別的發展簡史和應用模式識別的主要方法模式識別的系統和例項幾個相關的數學概念1、模式和模式識別的概念 什麼是模式(Pattern)? 廣義地說,存在於時間和空間中可觀察的事物,如果我們可以區別他們是否相同或是否相似,都可以稱之為
代理模式的自我理解(一)
delegate的函式往往要通過某些事件的觸發,才會自動呼叫的;比如uitableview的didselectrow函式,由於tableview.delegate=self等於自身,所以當觸發這個事件的時候,就會呼叫協議中的一個方法,而這個方法的實現就由self來實現,還有
c語言-樹的基礎知識(一)
相交 ges 最大 .cn nbsp 分享 blog com lin 第一、樹的定義: 1.有且只有一個稱為根的節點 2.有若幹個互不相交的子樹,這些子樹本身也是一顆樹 第二、專業術語: 樹的深度:從根節點到最低層,節點的層數 ,稱之為樹的深度。
Linux進程相關的內容及命令小結(一)
進程 linux概念:進程,一個活動的程序實體的副本,擁有生命周期,一個進程可能包含一個或多個執行流; 進程的創建進程: 每個進程的組織結構是一致的; 內核在正常啟動並且全面接管硬件資源之後,會創建一個Init的進程;而這個名叫init的進程負責用戶空間的進程管理; CentOS5及以前:SysV In