分享
  1. 首页
  2. 文章

gof23行为类模式(golang版)

菟潞寺沙弥 · · 2101 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

命令模式

image

命令模式是一个高内聚的模式,其定义:将一个请求封装成一个对象,从而让你使用不同的请求客户端参数化,对请求排除或者记录请求日志,可以提供命令的撤销和恢复功能。

命令模式包含如下角色:

  • Command: 抽象命令类
    需要执行的所有命令得出在这里声明。
  • ConcreteCommand: 具体命令类
    负责实现在Command角色中定义的接口
  • Invoker: 调用者
    开始执行命令的角色,它会调用在Command角色中定义的接口。
  • Receiver: 接收者
    该角色就是干活的角色,命令传递到这里是应该被执行的

命令模式的优点

  • 类间解耦
    调用者角色与接收者角色之间没有任何依赖关系,调用者实现功能时只须调用Command抽象类的execute方法就可以,不需要了解到底是哪个接收者执行
  • 可扩展性
    Command的子类可以非常容易地扩展,而调用者Invoker和高层次的模块Client不产生严重的代码耦合

命令模式的缺点

偏偏模式的缺点就是膨胀,如果有N个命令,问题就出来了,Command的子类会有N个。

package main
import (
 "fmt"
)
/**
Command: 抽象命令类
ConcreteCommand: 具体命令类
Invoker: 调用者
Receiver: 接收者
 */
// receiver
type TV struct {
}
func (p TV) Open() {
 fmt.Println("play...")
}
func (p TV) Close() {
 fmt.Println("stop...")
}
//command
type Command interface {
 Press()
}
//ConcreteCommand
type OpenCommand struct {
 tv TV
}
func (p OpenCommand) Press() {
 p.tv.Open()
}
//ConcreteCommand
type CloseCommand struct {
 tv TV
}
func (p CloseCommand) Press() {
 p.tv.Close()
}
//invoker
type Invoke struct {
 cmd Command
}
func (p *Invoke) SetCommand(cmd Command) {
 p.cmd = cmd
}
func (p *Invoke) Do() {
 p.cmd.Press()
}
type OpenCloseCommand struct {
 index int
 cmds []Command
}
func NewOpenCLoseCommand() *OpenCloseCommand {
 openCLose := &OpenCloseCommand{}
 openCLose.cmds = make([]Command, 2)
 return openCLose
}
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() {
 //单一命令
 tv := TV{}
 openCommand := OpenCommand{tv}
 invoker := Invoke{openCommand}
 invoker.Do()
 closeCommand := CloseCommand{tv}
 invoker.SetCommand(closeCommand)
 invoker.Do()
 //复合命令
 fmt.Println("############复合命令###############")
 openClose := NewOpenCLoseCommand()
 openClose.AddCommand(openCommand)
 openClose.AddCommand(closeCommand)
 invoker.SetCommand(openClose)
 invoker.Do()
}

中介者模式

image
image

中介者模式的定义为:用一个中介对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

中介者模式化多对多依赖为一对多依赖。

中介者模式由以下部分组成

  • Mediator: 抽象中介者
    抽象中介者角色定义统一的接口,用于各同事角色之间的通信
  • ConcreteMediator: 具体中介者
    具体中介者角色通过协调各同事角色实现协作行为,因此它必须依赖于各个同事角色
  • Colleague: 抽象同事类
    每一个同事角色都知道中介者角色,而且与其他的同事角色通信的时候,一定要通过中介者角色协作。
  • ConcreteColleague: 具体同事类
    每个同事类的行为分为两种:一种是再带本身的行为,比如改变对象本身的状态,处理自己的行为等,这种行为叫做自发行为,与其他的同事类或中介者没有任何的依赖;第二种是必须依赖中介者才能完成的行为,叫做依赖方法。
package behavior
import "fmt"
/**
Mediator: 抽象中介者
ConcreteMediator: 具体中介者
Colleague: 抽象同事类
ConcreteColleague: 具体同事类
 */
//mediator 及 ConcreteMediator
type UnitedNations interface {
 ForwardMessage(message string, country Country)
}
type UnitedNationsSecurityCouncil struct {
 USA
 Iraq
}
func (unsc UnitedNationsSecurityCouncil) ForwardMessage(message string, country Country) {
 switch country.(type) {
 case USA:
 unsc.Iraq.GetMessage(message)
 case Iraq:
 unsc.USA.GetMessage(message)
 default:
 fmt.Printf("The country is not a member of UNSC")
 }
}
type Country interface {
 SendMessage(message string)
 GetMessage(message string)
}
//Colleague以及ConcreteColleague类
type USA struct {
 UnitedNations
}
func (usa USA) SendMessage(message string) {
 usa.UnitedNations.ForwardMessage(message, usa)
}
func (usa USA) GetMessage(message string) {
 fmt.Printf("美国收到对方消息: %s\n", message)
}
type Iraq struct {
 UnitedNations
}
func (iraq Iraq) SendMessage(message string) {
 iraq.UnitedNations.ForwardMessage(message, iraq)
}
func (iraq Iraq) GetMessage(message string) {
 fmt.Printf("伊拉克收到对方消息: %s\n", message)
}

client

package main
import "gof23/behavior"
func main() {
 tMediator := behavior.UnitedNationsSecurityCouncil{}
 usa := behavior.USA{tMediator}
 iraq := behavior.Iraq{tMediator}
 tMediator.USA = usa
 tMediator.Iraq = iraq
 usa.SendMessage("停止大规模杀伤性武器的研发,否则发动战争")
 iraq.SendMessage("我们没有研发大规模杀伤性武器,也不怕战争")
}

有疑问加站长微信联系(非本文作者)

本文来自:Segmentfault

感谢作者:菟潞寺沙弥

查看原文:gof23行为类模式(golang版)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
2101 次点击
1 回复 | 直到 2018年12月11日 11:56:16
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏