30

gof23行为类模式(golang版)

 5 years ago
source link: https://studygolang.com/articles/16778?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

命令模式

1460000017308304?w=714&h=370

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

命令模式包含如下角色:

  • 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()
}

中介者模式

1460000017308305

1460000017308306

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

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

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

  • 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("我们没有研发大规模杀伤性武器,也不怕战争")
}

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK