go语言设计模式之命令模式(字节教育)

命令模式

命令模式是将一个请求封装为一个对象,从而使我们可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。命令模式是一种对象行为模式,其别名为动作模式或事务模式。

优点

  1. 一个调用者想创建一个对象,只知道对象名称就可以了;
  2. 扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以;
  3. 屏蔽产品的具体实现,调用者只关心产品的接口;

命令模式中有如下几个角色

Command:命令
Invoker:调用者
Receiver:接受者
Client:客户端
它们的关系可以这么来描述:客户端通过调用者发送命令,命令调用接受者执行相应操作。

代码

//电视类
type TV struct {
}

func (p TV) Open() {
	fmt.Println("Play...")
}

func (p TV) Close() {
	fmt.Println("Stop...")
}

//遥控器上的按键
type Command interface {
	Press()
}

type OpenCommand struct {
	tv TV
}

func (p OpenCommand) Press() {
	p.tv.Open()
}

type CloseCommand struct {
	tv TV
}

func (p CloseCommand) Press() {
	p.tv.Close()
}

//调用者(遥控器)
type Invoker struct {
	cmd Command
}

func (p *Invoker) SetCommand(cmd Command) {
	p.cmd = cmd
}

func (p *Invoker) Do() {
	p.cmd.Press()
}

//客户端
func main() {
	var tv TV
	openCommand := OpenCommand{tv}

	invoker := Invoker{openCommand}

	invoker.Do()

	invoker.SetCommand(CloseCommand{tv})

	invoker.Do()
}

命令模式实现起来也很简单,它降低了系统的耦合度,并且还可以任意扩展使用不需要修改代码,开闭原则体现的淋漓尽致。

接下来介绍复合命令,也叫宏命令,复合命令其实说白了就是将多个命令保存起来,通过遍历这个集合来分别调用各个命令。

package main

import "fmt"

//电视类
type TV struct {
}

func (p TV) Open() {
	fmt.Println("Play...")
}

func (p TV) Close() {
	fmt.Println("Stop...")
}

//遥控器上的按键
type Command interface {
	Press()
}

type OpenCommand struct {
	tv TV
}

func (p OpenCommand) Press() {
	p.tv.Open()
}

type CloseCommand struct {
	tv TV
}

func (p CloseCommand) Press() {
	p.tv.Close()
}

//调用者(遥控器)
type Invoker struct {
	cmd Command
}

func (p *Invoker) SetCommand(cmd Command) {
	p.cmd = cmd
}

func (p *Invoker) Do() {
	p.cmd.Press()
}


func NewOpenCloseCommand() *OpenCloseCommand {
	var openClose *OpenCloseCommand = &OpenCloseCommand{}
	openClose.cmds = make([]Command, 2)
	return openClose
}

type OpenCloseCommand struct {
	index int
	cmds  []Command
}

func (p *OpenCloseCommand) AddCommand(cmd Command) {
	p.cmds[p.index] = cmd
	p.index++
}

func (p OpenCloseCommand) Press() {
	for _, item := range p.cmds {
		item.Press()
	}
}

func main() {
	var tv TV
	var openClose *OpenCloseCommand = NewOpenCloseCommand()
	openClose.AddCommand(OpenCommand{tv})
	openClose.AddCommand(CloseCommand{tv})

	invoker := Invoker{openClose}
	invoker.SetCommand(openClose)
	invoker.Do()

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值