首页 > 其他分享 >10-Go设计模式-命令模式

10-Go设计模式-命令模式

时间:2022-10-17 14:45:54浏览次数:74  
标签:10 请求 接收者 命令 func CmdList Go 设计模式 type

命令模式

样例代码
/*
命令模式
将一个请求封装为一个对象,从而让我们可用不同的请求对客户进行参数化;
对请求排队或者记录请求日志,以及支持可撤销的操作。
命令模式是一种对象行为型模式,其别名为动作(Action)模式或事务(Transaction)模式。
命令模式可以将请求发送者和接收者完全解耦,
发送者与接收者之间没有直接引用关系,发送请求的对象只需要知道如何发送请求,而不必知道如何完成请求。


命令模式的优缺点
优点:
(1) 降低系统的耦合度。
	由于请求者与接收者之间不存在直接引用,因此请求者与接收者之间实现完全解耦,相同的请求者可以对应不同的接收者,
	同样,相同的接收者也可以供不同的请求者使用,两者之间具有良好的独立性。
(2) 新的命令可以很容易地加入到系统中。
	由于增加新的具体命令类不会影响到其他类,因此增加新的具体命令类很容易,无须修改原有系统源代码,甚至客户类代码,满足“开闭原则”的要求。
(3) 可以比较容易地设计一个命令队列或宏命令(组合命令)。

缺点:
使用命令模式可能会导致某些系统有过多的具体命令类。
因为针对每一个对请求接收者的调用操作都需要设计一个具体命令类,因此在某些系统中可能需要提供大量的具体命令类,这将影响命令模式的使用。


适用场景
(1) 系统需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互。
	请求调用者无须知道接收者的存在,也无须知道接收者是谁,接收者也无须关心何时被调用。
(2) 系统需要在不同的时间指定请求、将请求排队和执行请求。一个命令对象和请求的初始调用者可以有不同的生命期,
	换言之,最初的请求发出者可能已经不在了,而命令对象本身仍然是活动的,可以通过该命令对象去调用请求接收者,
	而无须关心请求调用者的存在性,可以通过请求日志文件等机制来具体实现。
(3) 系统需要将一组操作组合在一起形成宏命令。
*/

package _1_command_mode

import "fmt"

//=================================== 医生 ===================================================
//医生-命令接收者
type Doctor struct{}

func (d *Doctor) treatEye() {
	fmt.Println("医生治疗眼睛")
}

func (d *Doctor) treatNose() {
	fmt.Println("医生治疗鼻子")
}

//================================== 病单 ====================================================
//抽象的命令
type Command interface {
	Treat()
}

//治疗眼睛
type CommandTreatEye struct {
	doctor *Doctor
}

func (c *CommandTreatEye) Treat() {
	c.doctor.treatEye()
}

//治疗鼻子
type CommandTreatNose struct {
	doctor *Doctor
}

func (c *CommandTreatNose) Treat() {
	c.doctor.treatNose()
}

//护士-调用命令者
type Nurse struct {
	CmdList []Command
}

//发送病单,发送命令的方法
func (n *Nurse) Notify() {
	if n.CmdList == nil {
		return
	}

	for _, cmd := range n.CmdList {
		cmd.Treat() //执行病单绑定的命令(这里会调用病单已经绑定的医生诊断方法)
	}
}

//=================================== 病人 ========================================
func BingRen() {
	//依赖病单,通过填写病单,让医生看病
	docter := new(Doctor)
	//治疗眼睛的病单
	cmdEye := CommandTreatEye{doctor: docter}
	//治疗鼻子的病单
	cmdNose := CommandTreatNose{doctor: docter}

	//护士
	nurse := new(Nurse)
	//手机管理病单
	nurse.CmdList = append(nurse.CmdList, &cmdEye)
	nurse.CmdList = append(nurse.CmdList, &cmdNose)

	//执行病单指令
	nurse.Notify()
}

测试代码

package _1_command_mode

import "testing"

func TestDocter(t *testing.T) {
	BingRen()
}

例子

/*
练习:
路边撸串烧烤场景, 有烤羊肉,烧鸡翅命令,有烤串师傅,和服务员。
根据命令模式,设计烤串场景
*/
package _1_command_mode

import "fmt"

//=========================== 烤串师傅 ==========================
type Cooker struct{}

func (c *Cooker) MakeChicken() {
	fmt.Println("烤串师傅烤了鸡肉串")
}

func (c *Cooker) MakeChuaner() {
	fmt.Println("烤串是否烤了羊肉串")
}

//=========================== 烤串 ==============================
//抽象命令
type Command2 interface {
	Make()
}

type CommandCookChicken struct {
	cooker *Cooker
}

func (c *CommandCookChicken) Make() {
	c.cooker.MakeChicken()
}

type CommandCookChuaner struct {
	cooker *Cooker
}

func (c *CommandCookChuaner) Make() {
	c.cooker.MakeChuaner()
}

//=========================== 服务员 ============================
type WaiterMM struct {
	CmdList []Command2
}

func (w *WaiterMM) Notify() {
	if w.CmdList == nil {
		return
	}

	for _, cmd := range w.CmdList {
		cmd.Make()
	}
}

//=========================== 顾客 =============================
func consumer() {
	cooker := new(Cooker)
	cmdChicken := CommandCookChicken{cooker: cooker}
	cmdChuaner := CommandCookChuaner{cooker: cooker}

	mm := new(WaiterMM)
	mm.CmdList = append(mm.CmdList, &cmdChicken)
	mm.CmdList = append(mm.CmdList, &cmdChuaner)

	mm.Notify()
}

package _1_command_mode

import "testing"

func TestCooker(t *testing.T) {
	consumer()
}

标签:10,请求,接收者,命令,func,CmdList,Go,设计模式,type
From: https://www.cnblogs.com/lichengguo/p/16799139.html

相关文章

  • window10系统下Pytorch安装教程
    1、Pytorch介绍PyTorch是一个基于Torch的Python开源机器学习库,用于自然语言处理等应用程序它主要由Facebook的人工智能小组开发,不仅能够实现强大的GPU加速,同时还支持动态神......
  • 配置win10+anaconda3+python3.6+pytorch
    1.下载安装anaconda如果下载太慢,可以选择清华镜像下载:​​https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/​​​2.配置环境变量3.修改镜像如果按照提示http......
  • CF1736C1 Good Subarrays (Easy Version)
    题目传送门思路给出一种不需要脑子的做法。首先我们把每个\(a_i\)都减去\(i\),这样原问题就转化为对于每一个左端点\(i\),寻找一段连续的区间,使得这段区间的最小值加......
  • LFM Oversea 每周策略晨报 2022-10-17
    盘面数据 国庆后上证指数下穿3000 点,随后迎来连续上涨,上周上证指数上涨1.57%,深证成指上涨3.18%,创业板指数上涨6.35%。上周A 股日均成交额6982亿元,较上周环比+......
  • 数据集 | 2010-2021年玻利瓦尔-美元价格数据集
    下载数据集请登录爱数科该数据集包含2010年至2021年间委内瑞拉货币玻利瓦尔与美元之间的汇率数据,为经济通胀提供了重要依据。1.字段描述2.数据预览3.字段诊断信息4.数据......
  • 数据集 | Google图书数据集
    该数据是从Google图书商店获取的。使用GoogleAPI来获取数据。数据集中为每本书收集了九种属性。1.字段描述2.数据预览3.字段诊断信息......
  • 2022.10.15 总结
    C中位数定义为第\(\lfloor\dfrac{n}{2}\rfloor+1\)个数。现有一个数组\(a\),\(n\le10^5\).对于\(1\lel\ler\len\),求区间\([l,r]\)的中位数,把这些中位数......
  • Winform 窗体重命名(改名)后,设计模式对窗体的任何修改都无效,执行结果为改名前的窗体(一个
    (如图)1.新建Winform窗体应用程序  2.窗体设计器不关闭,直接改名 3.设计窗体 4.运行程序,结果(窗体空白) 5.解决方案   5.1丢弃设计,直接关闭设计窗体,重新......
  • AT4363 [ARC102D] Revenge of BBuBBBlesort!
    题面传送门奇妙的题目。首先有一个看上去很对的做法:我们从\(a_i=i\)向当前序列移动,每次满足当前位置上不满足的第一个,如果换不过去那么就是NO,否则YES。但是很遗憾这个东......
  • 10.数据库设计
    数据库设计一、数据库设计的三范式第一范式:是对属性的原子性,要求属性具有原子性,不可再分解。如下表结构设计createtableStudent( StuIdvarchar(20)primarykey,......