命令模式(Command Pattern)是一种数据驱动的设计模式,它属于行为型模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。
命令模式的实现代码
package main
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 (cmd *CommandTreatEye) Treat() {
cmd.doctor.treatEye()
}
//治疗鼻子的病单
type CommandTreatNose struct {
doctor *Doctor
}
func (cmd *CommandTreatNose) Treat() {
cmd.doctor.treatNose()
}
//护士-调用命令者
type Nurse struct {
CmdList []Command //收集的命令集合
}
//发送病单,发送命令的方法
func (n *Nurse) Notify() {
if n.CmdList == nil {
return
}
for _, cmd := range n.CmdList {
cmd.Treat() //执行病单绑定的命令(这里会调用病单已经绑定的医生的诊断方法)
}
}
//病人
func main() {
//依赖病单,通过填写病单,让医生看病
doctor := new(Doctor)
//治疗眼睛的病单
cmdEye := CommandTreatEye{doctor}
//治疗鼻子的病单
cmdNose := CommandTreatNose{doctor}
//护士
nurse := new(Nurse)
//收集管理病单
nurse.CmdList = append(nurse.CmdList, &cmdEye)
nurse.CmdList = append(nurse.CmdList, &cmdNose)
//执行病单指令
nurse.Notify()
}
终端输出
命令模式的代码拆分
1.项目的准备工作
找到 go 的 GOPATH
$ go env //可以查看 GOPATH
在 GOPATH 目录下创建3个文件夹
1.bin文件夹 -- 存放编译后的二进制文件
2.pkg文件夹 -- 存放编译后的库文件
3.src文件夹 -- 存放源码文件
2.创建文件夹
// -- 在项目文件夹 command_case 里创建新文件夹
// command -- 存放装饰者的全部文件
3.接口文件 -- command文件夹
文件1 -- command.go
package command
//抽象的命令
type Command interface {
Treat()
}
4.结构体文件 -- command文件夹
文件1 -- doctor.go
package command
import "fmt"
//医生-命令接收者
type Doctor struct {}
func (d *Doctor) TreatEye() {
fmt.Println("医生治疗眼睛")
}
func (d *Doctor) TreatNose() {
fmt.Println("医生治疗鼻子")
}
文件2 -- commandtreateye.go
package command
//治疗眼睛的病单
type CommandTreatEye struct {
Doctor *Doctor
}
func (cmd *CommandTreatEye) Treat() {
cmd.Doctor.TreatEye()
}
文件3 -- commandtreatnose.go
package command
//治疗鼻子的病单
type CommandTreatNose struct {
Doctor *Doctor
}
func (cmd *CommandTreatNose) Treat() {
cmd.Doctor.TreatNose()
}
文件4 -- nurse.go
package command
//护士-调用命令者
type Nurse struct {
CmdList []Command //收集的命令集合
}
//发送病单,发送命令的方法
func (n *Nurse) Notify() {
if n.CmdList == nil {
return
}
for _, cmd := range n.CmdList {
cmd.Treat() //执行病单绑定的命令(这里会调用病单已经绑定的医生的诊断方法)
}
}
5.主文件 -- main.go 在项目文件夹
package main
import (
"design/command_case/command"
)
//病人
func main() {
//依赖病单,通过填写病单,让医生看病
Doctor := new(command.Doctor)
//治疗眼睛的病单
cmdEye := command.CommandTreatEye{Doctor}
//治疗鼻子的病单
cmdNose := command.CommandTreatNose{Doctor}
//护士
nurse := new(command.Nurse)
//收集管理病单
nurse.CmdList = append(nurse.CmdList, &cmdEye)
nurse.CmdList = append(nurse.CmdList, &cmdNose)
//执行病单指令
nurse.Notify()
}