Go设计模式--命令模式

来源:面包芯语  发布时间:2023-05-10 08:13:05 

直接这么描述听起来比较抽象,下面我们结合UML类图详细看一下命令模式内部这几种基础组件的特性和具有的行为。

UML类图

命令模式的构成如下图所示


(资料图片)

请求的接收者Receiver我们做了简化,根据实际场景复杂度的需要我们也可以进一步抽象出接口和实现类,图中表示的命令模式一共由五种角色构成,下面详细解释下它们各自的特性和具有的行为

发送者是通常我们能接触到的终端,比如电视的遥控器,点击音量按钮发送加音量的命令,电视机里的芯片就是接收者负责完成音量添加的处理逻辑。

下面我们通过一个让PS5完成各种操作的例子,结合Golang代码实现理解一下用代码怎么实现命令模式。

代码示例

假设PS5的CPU支持A、B、C三个命令操作,

"本文使用的完整可运行源码去公众号「网管叨bi叨」发送【设计模式】即可领取"typeCPUstruct{}func(CPU)ADoSomething(){fmt.Println("adosomething")}func(CPU)BDoSomething(){fmt.Println("bdosomething")}typePS5struct{cpuCPU}func(pPS5)ACommand(){p.cpu.ADoSomething()}func(pPS5)BCommand(){p.cpu.ADoSomething()}funcmain(){cpu:=CPU{}ps5:=PS5{cpu}ps5.ACommand()ps5.BCommand()}

后续还可能会给CPU增加其他命令操作,以及需要支持命令宏(即命令组合操作)。如果每次都修改PS5的类定义,显然不符合面向对象开闭原则(Open close principle)的设计理念。

通过命令模式,我们把PS5抽象成命令发送者、CPU对象作为执行业务逻辑的命令接收者,然后引入引入Command 接口把两者做解耦,来满足开闭原则。

下面看一下用命令模式解耦后的代码实现,模式中各个角色的职责、实现思路等都在代码注释里做了标注,咱们直接看代码吧。‍‍‍‍‍‍‍

"本文使用的完整可运行源码去公众号「网管叨bi叨」发送【设计模式】即可领取"//命令接收者,负责逻辑的执行typeCPUstruct{}func(CPU)ADoSomething(paramint){fmt.Printf("adosomethingwithparam%v\n",param)}func(CPU)BDoSomething(param1string,param2int){fmt.Printf("bdosomethingwithparams%vand%v\n",param1,param2)}func(CPU)CDoSomething(){fmt.Println("cdosomethingwithnoparams")}//接口中仅声明一个执行命令的方法Execute()typeCommandinterface{Execute()}//命令对象持有一个指向接收者的引用,以及请求中的所有参数,typeACommandstruct{cpu*CPUparamint}//命令不会进行逻辑处理,调用Execute方法会将发送者的请求委派给接收者对象。func(aACommand)Execute(){a.cpu.ADoSomething(a.param)a.cpu.CDoSomething()//可以执行多个接收者的操作完成命令宏}funcNewACommand(cpu*CPU,paramint)Command{returnACommand{cpu,param}}"本文使用的完整可运行源码去公众号「网管叨bi叨」发送【设计模式】即可领取"typeBCommandstruct{statebool//Command里可以添加些状态用作逻辑判断cpu*CPUparam1stringparam2int}func(bBCommand)Execute(){ifb.state{return}b.cpu.BDoSomething(b.param1,b.param2)b.state=trueb.cpu.CDoSomething()}funcNewBCommand(cpu*CPU,param1string,param2int)Command{returnBCommand{false,cpu,param1,param2}}typePS5struct{commandsmap[string]Command}// SetCommand方法来将 Command 指令设定给PS5。func(p*PS5)SetCommand(namestring,commandCommand){p.commands[name]=command}//DoCommand方法选择要执行的命令func(p*PS5)DoCommand(namestring){p.commands[name].Execute()}funcmain(){cpu:=CPU{}// main方法充当客户端,创建并配置具体命令对象, 完成命令与执行操作的接收者的关联。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")}

本文的完整源码,已经同步收录到我整理的电子教程里啦,可向我的公众号「网管叨bi叨」发送关键字【设计模式】领取。

公众号「网管叨bi叨」发送关键字【设计模式】领取。

总结

关于命令模式的学习和实践应用,推荐有Java背景的同学看一下阿里开源的框架COLA 3.0,里面融合了不少DDD的概念,其中的Application层主要就是各种Command、Query对象封装了客户端的请求,它们的Execute方法负责将请求转发给Domain层进行处理从而完成业务逻辑。

最后我们再来总结一下命令模式的优缺点。

命令模式的优点

命令模式的缺点

扫码关注公众号「网管叨bi叨」

给网管个星标,第一时间吸我的知识

网管整理了一本《Go 开发参考书》收集了70多条开发实践。去公众号回复【gocookbook】领取!还有一本《k8s 入门实践》讲解了常用软件在K8s上的部署过程,公众号回复【k8s】即可领取!

觉得有用就点个在看

标签:

关闭

Go设计模式--命令模式

大家好,这里是每周都陪你进步的网管,假期归来咱们继续更新设计模式系列,这次要和大家一起学习的是命令模更多

2023-05-10 08:13:05

绝对值是什么意思举例子_绝对值是什么

1、绝对值的几何意义是指数轴上一个数对应的点到原点的距离;2、绝对值的代数意义,即数学中的绝对值是指一更多

2023-05-10 06:53:48

美联储6月加息25个基点的概率为18.9%;

美联储6月加息25个基点的概率为18 9%;据CME“美联储观察”:美联储6月维持利率不变的概率为81 1%,加息25个更多

2023-05-10 06:03:17

银行存钱也有“门道”?为了资金安全,有三种存钱

自从经历了公共卫生事件以后,人们深刻体会到“存钱在手,遇事不慌”的道理,有越来越多人开始积极储蓄,而更多

2023-05-10 04:49:49

每日时讯!首例出生前胎儿脑部手术成功实施

(记者刘霞)美国医生首次成功对仍在子宫内的胎儿实施了脑部手术,以修复其畸形的血管。鉴于此,波士顿儿童更多

2023-05-10 03:01:21

天天快看点丨steam更新失败缺少已下载文件_steam

1、steam更新失败怎么办?  steam升级问题:steam更新失败出现steamneedstobeonl更多

2023-05-10 01:00:24

新疆妇联发布2023年16项重点民生工作

9日,新疆妇联举行5—6月工作新闻通气会。 喇小飞 摄中新网乌鲁木齐5月9日电(喇小飞刘一栋)“今年妇联16更多

2023-05-09 22:34:06

热讯:2023年湖北省住培基地院领导政策理论培训班

2023年湖北省住培基地院领导政策理论培训班在汉举办---2023年湖北省住培基地院领导政策理论培训班在汉举办更多

2023-05-09 22:01:21

世界快播:*ST大通:深交所拟决定终止公司股票上

*ST大通公告,公司近日收到深交所下发的《事先告知书》,截至4月30日,公司未能在法定期限内披露2022年年度更多

2023-05-09 21:11:49

海南银行:取消发行“23海南银行CD202”

取消发行“23海南银行CD202”更多

2023-05-09 20:26:00