設計模式 命令模式 Go語言描述

2021-07-10 07:43:02 字數 3025 閱讀 7314

說起命令,大家第一反應可能就是我們平時敲的各種命令,啪啪啪幾行命令下去就可以完成一些功能,在看到命令模式這個詞後,可能大家也會和我一樣認為這裡的命令就是執行一些簡單任務的功能,然而並不是,這裡的命令更多的像是我們發出的請求或者電視遙控器的按鍵.這樣吧,咱們先來看看命令模式的定義,然後再從生活中找實際的例子對比一下.

命令模式是將乙個請求封裝為乙個物件,從而使我們可用不同的請求對客戶進行引數化;對請求排隊或者記錄請求日誌,以及支援可撤銷的操作.命令模式是一種物件行為型模式,其別名為動作模式或事務模式.

在命令模式中有如下幾個角色:

command: 命令

invoker: 呼叫者

receiver: 接受者

client: 客戶端

他們的關係可以這麼來描述:

客戶端通過呼叫者傳送命令,命令呼叫接收者執行相應操作.

其實命令模式也很簡單,不過不知道大家發現沒有,在上述描述中呼叫者和接收者並不知道對方的存在,也就是說他們之間是解耦合的.

還是用遙控器的例子來解釋一下吧,遙控器對應上面的角色就是呼叫者,電視就是接收者,命令呢?對應的就是遙控器上的按鍵,最後客戶端就是我們人啦,當我們想開啟電視的時候,就會通過遙控器(呼叫者)的電源按鈕(命令)來開啟電視(接收者),在這個過程中遙控器是不知道電視的,但是電源按鈕是知道他要控制誰的什麼操作.

… 哎呀, 語文不太好,突然發現越描述越不容易讓人理解了呢? 還是用**來實現一下上面遙控器的例子吧.我們對照著上面的角色乙個個的去實現.

接收者,也就是一台大大的電視,

// receiver

type tv struct{}

func (p tv) open()

func (p tv) close()

這台電視弱爆了,只有開啟和關閉兩個功能,對應的就是上面**中的openclose兩個方法,雖然很簡單,不過我們確實造出了一台電視(估計還是彩色的).

下面,我們再來實現命令,也就是遙控器上的按鍵,因為電視只有開啟和關閉功能,所以按鍵我們也只提供兩個,多了用不上.

// command

type command inte***ce

type opencommand struct

func (p opencommand) press()

type closecommand struct

func (p closecommand) press()

首先我們定義了乙個命令介面,只有乙個方法就是press,當我們按下按鍵時會去呼叫這個方法,然後我們果然只實現了兩個按鍵,分別是opencommandclosecommand,這兩個實現中都儲存著一台電視的控制代碼,並且在press方法中根據功能去呼叫了這個tv的相應方法來完成正確的操作.

還有什麼我們沒有實現? 呼叫者,也就是遙控器了,來看看遙控器怎麼實現吧.

// sender

type invoker struct

func (p *invoker) setcommand(cmd command)

func (p invoker) do()

在遙控器中我們有乙個command型別的變數,並且提供了setcommand方法來設定命令,那我們按下遙控器上的鍵對應哪個方法呢?看看do方法,我們直接呼叫了命令的press方法,這個時候客戶端(就是我們人)拿起遙控器,瞅準了開啟按鈕(setcommand),並且按鈕該鍵(do),按鍵被按下(press),電視開啟了(open).

那麼最後,來看看客戶端怎麼去呼叫吧,

func main() 

invoker := invoker

invoker.do()

invoker.setcommand(closecommand)

invoker.do()

}

命令模式實現起來也很簡單,它降低了我們這個系統的耦合度,並且我們還可以任意拓展命令使用而不需要修改**,開閉原則體現的淋漓盡致.

現在大家應該對命令模式有了乙個直觀的認識吧, 不過大家有沒有發現乙個問題,我們的遙控器在使用某個命令的時候只有set後才能用,也就是說每次只能使用乙個命令,那有沒有更好的辦法來預裝命令呢?肯定是有的,這就是我們接下來要介紹的復合命令,也叫做巨集命令,復合命令其實說白了就是將多個命令儲存起來,通過遍歷這個集合來分別呼叫各個命令.

func newopenclosecommand() *openclosecommand 

openclose.cmds = make(command,2)

return openclose

}type openclosecommand struct

func (p *openclosecommand) addcommand(cmd command)

func (p openclosecommand) press()

}func main() )

openclose.addcommand(closecommand)

invoker.setcommand(openclose)

invoker.do()

}

我們定義了乙個openclosecommand,這裡面用乙個切片來儲存各個命令,並通過addcommand方法來王裡面新增命令,openclosecommand實現了press方法,所以本質上他也是乙個命令,我們呼叫他的press方法來遍歷儲存的command,並呼叫每乙個的press方法.

到這裡,命令模式我們就介紹完了,命令模式具有很高的擴充套件性,遵循了開閉原則,所以減少了修改**引入bug的可能性,快來想一想你的**中哪些地方可以用命令模式來解決吧.

設計模式 介面卡模式 Go語言描述

說起介面卡模式,相信很多做android的同學第一印象就是adapterview的adapter,那它是幹嘛用的呢?為什麼要叫adapter呢?要了解這個問題,我們首先來看看介面卡模式的定義 將乙個類的介面轉換成客戶希望的另外乙個介面。介面卡模式使得原本由於介面不相容而不能一起工作的那些類可以一起工...

go語言設計模式之命令模式 位元組教育

命令模式是將乙個請求封裝為乙個物件,從而使我們可用不同的請求對客戶進行引數化 對請求排隊或者記錄請求日誌,以及支援可撤銷的操作。命令模式是一種物件行為模式,其別名為動作模式或事務模式。乙個呼叫者想建立乙個物件,只知道物件名稱就可以了 擴充套件性高,如果想增加乙個產品,只要擴充套件乙個工廠類就可以 遮...

策略設計模式 Go語言設計模式 策略

策略設計模式 策略模式是一種行為設計模式。此模式允許在執行時不需要更改物件的型別定義時就能改變該物件的行為。用乙個例子來理解策略模式。假設構建乙個快取inmemorycache,它擁有固定的容量大小,當達到其最大容量時,快取中的某些舊項需要被逐出,這種驅逐可以通過幾種演算法來實現 現在的問題是如何將...