成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Go設(shè)計(jì)模式--命令模式

開發(fā) 前端
命令模式的結(jié)果其實(shí)就是接收方的執(zhí)行結(jié)果,但是為了以命令的形式進(jìn)行架構(gòu)、解耦請求與實(shí)現(xiàn),引入了額外類型結(jié)構(gòu)(引入了請求方與抽象命令接口),增加了理解上的困難。

大家好,這里是每周都陪你進(jìn)步的網(wǎng)管,假期歸來咱們繼續(xù)更新設(shè)計(jì)模式系列,這次要和大家一起學(xué)習(xí)的是命令模式,如果你對領(lǐng)域驅(qū)動設(shè)計(jì)感興趣,這個(gè)模式一定要好好學(xué),命令模式是DDD風(fēng)格的框架中高頻使用的一個(gè)模式。

命令模式是一種行為型模式。它通過將請求封裝為一個(gè)獨(dú)立的對象即命令對象,來解耦命令的調(diào)用者和接收者,使得調(diào)用者和接收者不直接交互。在命令對象里會包含請求相關(guān)的全部信息,每一個(gè)命令都是一個(gè)操作的請求: 請求方發(fā)出請求要求執(zhí)行一個(gè)操作; 接收方收到請求,并執(zhí)行操作。

命令模式的構(gòu)成

命令模式中有如下必須存在的基礎(chǔ)組件:

  • Receiver:命令的接收方,唯一包含業(yè)務(wù)邏輯的類,命令對象會將請求傳遞給它,它是請求的最終處理者
  • Command:命令對象,組裝了一個(gè)Receiver成員,并綁定實(shí)現(xiàn)了Receiver的一個(gè)特定行為的調(diào)用
  • Invoker:請求的發(fā)送者,組裝了Command成員,通過調(diào)用Command實(shí)例的execute()方法來觸發(fā)對應(yīng)的指令
  • Client:通過將Receiver實(shí)例和請求信息傳遞給Command構(gòu)造器來創(chuàng)建Command對象,之后會將創(chuàng)建的對象同Invoker綁定。

直接這么描述聽起來比較抽象,下面我們結(jié)合UML類圖詳細(xì)看一下命令模式內(nèi)部這幾種基礎(chǔ)組件的特性和具有的行為。

UML類圖

命令模式的構(gòu)成如下圖所示

圖片

請求的接收者Receiver我們做了簡化,根據(jù)實(shí)際場景復(fù)雜度的需要我們也可以進(jìn)一步抽象出接口和實(shí)現(xiàn)類,圖中表示的命令模式一共由五種角色構(gòu)成,下面詳細(xì)解釋下它們各自的特性和具有的行為

  1. 發(fā)送者(Invoker)負(fù)責(zé)對請求進(jìn)行初始化, 其中必須包含一個(gè)成員變量來存儲對于命令對象的引用。 發(fā)送者觸發(fā)命令, 而不是向接收者直接發(fā)送請求。 發(fā)送者并不負(fù)責(zé)創(chuàng)建命令對象,而是由客戶端負(fù)責(zé)調(diào)用構(gòu)造函數(shù)創(chuàng)建命令對象。
  2. 命令接口(Command) 通常接口中僅聲明一個(gè)執(zhí)行命令的方法 Execute()。
  3. 具體命令 (Concrete Commands) 會實(shí)現(xiàn)各種類型的請求。 命令對象自身并不完成工作, 而是會將調(diào)用委派給一個(gè)接收者對象。 接收者對象執(zhí)行方法所需的參數(shù)可以聲明為具體命令的成員變量。 一般會約定命令對象為不可變對象, 僅允許通過構(gòu)造函數(shù)對這些成員變量進(jìn)行初始化。
  4. 接收者 (Receiver) 處理業(yè)務(wù)邏輯的類。 幾乎任何對象都可以作為接收者。 命令對象只負(fù)責(zé)處理如何將請求傳遞到接收者的細(xì)節(jié), 接收者自己會完成實(shí)際的工作。
  5. 客戶端 (Client) 會創(chuàng)建并配置具體命令對象。 客戶端必須將包括接收者對象在內(nèi)的所有請求參數(shù)傳遞給命令對象的構(gòu)造函數(shù), 完成命令與執(zhí)行操作的接收者的關(guān)聯(lián)。

發(fā)送者是通常我們能接觸到的終端,比如電視的遙控器,點(diǎn)擊音量按鈕發(fā)送加音量的命令,電視機(jī)里的芯片就是接收者負(fù)責(zé)完成音量添加的處理邏輯。

下面我們通過一個(gè)讓PS5完成各種操作的例子,結(jié)合Golang代碼實(shí)現(xiàn)理解一下用代碼怎么實(shí)現(xiàn)命令模式。

代碼示例

假設(shè)PS5的CPU支持A、B、C三個(gè)命令操作,

"本文使用的完整可運(yùn)行源碼
去公眾號「網(wǎng)管叨bi叨」發(fā)送【設(shè)計(jì)模式】即可領(lǐng)取"

type CPU struct{}

func (CPU) ADoSomething() {
 fmt.Println("a do something")
}
func (CPU) BDoSomething() {
 fmt.Println("b do something")
}


type PS5 struct {
 cpu CPU
}

func (p PS5) ACommand() {
 p.cpu.ADoSomething()
}
func (p PS5) BCommand() {
 p.cpu.ADoSomething()
}
func main() {
 cpu := CPU{}
 ps5 := PS5{cpu}
 ps5.ACommand()
 ps5.BCommand()
}

后續(xù)還可能會給CPU增加其他命令操作,以及需要支持命令宏(即命令組合操作)。如果每次都修改PS5的類定義,顯然不符合面向?qū)ο箝_閉原則(Open close principle)的設(shè)計(jì)理念。

通過命令模式,我們把PS5抽象成命令發(fā)送者、CPU對象作為執(zhí)行業(yè)務(wù)邏輯的命令接收者,然后引入引入Command 接口把兩者做解耦,來滿足開閉原則。

下面看一下用命令模式解耦后的代碼實(shí)現(xiàn),模式中各個(gè)角色的職責(zé)、實(shí)現(xiàn)思路等都在代碼注釋里做了標(biāo)注,咱們直接看代碼吧。

"本文使用的完整可運(yùn)行源碼
去公眾號「網(wǎng)管叨bi叨」發(fā)送【設(shè)計(jì)模式】即可領(lǐng)取"
// 命令接收者,負(fù)責(zé)邏輯的執(zhí)行
type CPU struct{}

func (CPU) ADoSomething(param int) {
 fmt.Printf("a do something with param %v\n", param)
}
func (CPU) BDoSomething(param1 string, param2 int) {
 fmt.Printf("b do something with params %v and %v \n", param1, param2)
}
func (CPU) CDoSomething() {
 fmt.Println("c do something with no params")
}

// 接口中僅聲明一個(gè)執(zhí)行命令的方法 Execute()
type Command interface {
 Execute()
}

// 命令對象持有一個(gè)指向接收者的引用,以及請求中的所有參數(shù),
type ACommand struct {
 cpu *CPU
 param int
}
// 命令不會進(jìn)行邏輯處理,調(diào)用Execute方法會將發(fā)送者的請求委派給接收者對象。 
func (a ACommand) Execute() {
 a.cpu.ADoSomething(a.param)
 a.cpu.CDoSomething()// 可以執(zhí)行多個(gè)接收者的操作完成命令宏
}

func NewACommand(cpu *CPU, param int) Command {
 return ACommand{cpu, param}
}

"本文使用的完整可運(yùn)行源碼
去公眾號「網(wǎng)管叨bi叨」發(fā)送【設(shè)計(jì)模式】即可領(lǐng)取"
type BCommand struct {
 state bool // Command 里可以添加些狀態(tài)用作邏輯判斷
 cpu *CPU
 param1 string
 param2 int
}

func (b BCommand) Execute() {
 if b.state {
  return
 }
 b.cpu.BDoSomething(b.param1, b.param2)
 b.state = true
 b.cpu.CDoSomething()
}

func NewBCommand(cpu *CPU, param1 string, param2 int) Command {
 return BCommand{false,cpu, param1, param2}
}

type PS5 struct {
 commands map[string]Command
}

// SetCommand方法來將 Command 指令設(shè)定給PS5。
func (p *PS5) SetCommand(name string, command Command) {
 p.commands[name] = command
}
// DoCommand方法選擇要執(zhí)行的命令
func (p *PS5) DoCommand(name string) {
 p.commands[name].Execute()
}

func main() {
 cpu := CPU{}
    // main方法充當(dāng)客戶端,創(chuàng)建并配置具體命令對象, 完成命令與執(zhí)行操作的接收者的關(guān)聯(lián)。
 ps5 := PS5{make(map[string]Command)}
 ps5.SetCommand("a", NewACommand(&cpu, 1))
 ps5.SetCommand("b", NewBCommand(&cpu, "hello", 2))
 ps5.DoCommand("a")
 ps5.DoCommand("b")
}

本文的完整源碼,已經(jīng)同步收錄到我整理的電子教程里啦,可向我的公眾號「網(wǎng)管叨bi叨」發(fā)送關(guān)鍵字【設(shè)計(jì)模式】領(lǐng)取。

圖片

公眾號「網(wǎng)管叨bi叨」發(fā)送關(guān)鍵字【設(shè)計(jì)模式】領(lǐng)取。

總結(jié)

關(guān)于命令模式的學(xué)習(xí)和實(shí)踐應(yīng)用,推薦有Java背景的同學(xué)看一下阿里開源的框架COLA 3.0,里面融合了不少DDD的概念,其中的Application層主要就是各種Command、Query對象封裝了客戶端的請求,它們的Execute方法負(fù)責(zé)將請求轉(zhuǎn)發(fā)給Domain層進(jìn)行處理從而完成業(yè)務(wù)邏輯。

最后我們再來總結(jié)一下命令模式的優(yōu)缺點(diǎn)。

命令模式的優(yōu)點(diǎn)

  1. 通過引入中間件(抽象接口),解耦了命令請求與實(shí)現(xiàn)。
  2. 擴(kuò)展性良好,可以很容易地增加新命令。
  3. 支持組合命令,支持命令隊(duì)列。
  4. 可以在現(xiàn)有命令的基礎(chǔ)上,增加額外功能。比如日志記錄,結(jié)合裝飾器模式會更加靈活。

命令模式的缺點(diǎn)

  1. 具體命令類可能過多。
  2. 命令模式的結(jié)果其實(shí)就是接收方的執(zhí)行結(jié)果,但是為了以命令的形式進(jìn)行架構(gòu)、解耦請求與實(shí)現(xiàn),引入了額外類型結(jié)構(gòu)(引入了請求方與抽象命令接口),增加了理解上的困難。
責(zé)任編輯:武曉燕 來源: 網(wǎng)管叨bi叨
相關(guān)推薦

2023-04-10 09:20:13

設(shè)計(jì)模式訪客模式

2023-05-15 08:51:46

解釋器模式定義

2020-11-03 13:05:18

命令模式

2012-07-10 02:01:53

設(shè)計(jì)模式命令模式

2023-05-26 08:41:23

模式Go設(shè)計(jì)模式

2010-04-13 08:54:28

PHP設(shè)計(jì)模式命令模式

2023-03-21 07:57:37

Go語言設(shè)計(jì)模式

2023-03-27 00:20:48

2021-02-01 10:01:58

設(shè)計(jì)模式 Java單例模式

2023-03-06 08:46:12

2021-04-19 21:25:48

設(shè)計(jì)模式到元

2022-09-21 08:47:05

項(xiàng)目多線程對象

2020-08-21 07:23:50

工廠模式設(shè)計(jì)

2020-11-04 08:54:54

狀態(tài)模式

2013-11-26 16:09:34

Android設(shè)計(jì)模式

2020-10-23 09:40:26

設(shè)計(jì)模式

2022-01-12 13:33:25

工廠模式設(shè)計(jì)

2023-11-02 21:11:11

JavaScript設(shè)計(jì)模式

2009-10-19 09:49:37

Java命令模式

2021-11-28 22:33:01

Go選項(xiàng)模式
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 欧美日韩a | 久久久久se| 国产高清精品一区二区三区 | 成人免费视频网站在线观看 | 欧美激情国产日韩精品一区18 | 99久久精品免费看国产免费软件 | 人人亚洲 | 欧美福利视频 | 久久99精品国产麻豆婷婷 | 久久精品高清视频 | 日本中文字幕在线视频 | 国精产品一品二品国精在线观看 | 亚洲在线| 四虎影音 | 亚洲美女网站 | 91精品国产91久久久久福利 | 国产99久久久国产精品下药 | 精品国产乱码一区二区三区 | 成人在线免费观看 | 天堂在线中文 | 先锋资源站| 精品一二区| 日本人做爰大片免费观看一老师 | 精品在线观看入口 | 国产精品美女一区二区三区 | 91成人在线| 免费精品 | 精品国产青草久久久久96 | 91久久久久久久久久久久久 | 欧美一级淫片免费视频黄 | 久夜精品 | 欧洲一级毛片 | 亚洲高清免费视频 | 亚洲一区二区不卡在线观看 | av不卡一区| 毛片一级网站 | 亚洲精品久久久一区二区三区 | 亚洲欧美激情国产综合久久久 | 色综合久久88色综合天天 | 国产黄色大片 | 国产一区二区 |