【Go-设计模式】中介者模式 详解

shadowLogo

概念:

  1. 中介者模式(Mediator Pattern),用一个 中介对象 来封装 一系列的 对象交互
    中介者 使各个对象不需要 显式地相互引用,从而使其 耦合松散,而且可以 独立地改变 它们之间的 交互
  2. 中介者模式属于 行为型模式,使代码易于维护
  3. 比如 MVC 模式,C(Controller 控制器)是 M(Model 模型)和 V(View 视图)的中介者,在前后端交互时起到了中间人的作用

中介


UML:

uml

  • Mediator
    抽象中介者,定义了 同事对象中介者对象接口
  • ConcreteMediator
    具体的中介者对象,它需要知道 所有的具体的同事类,即以一个 集合 来管理所有同事,并完成相应的任务
  • Colleague
    抽象同事类,定义了 同事对象 的 基本功能
  • ConcreteColleague
    具体的同事类每个同事 只知道 自己的行为,而 不了解其他同事类的行为(方法),但是他们都 依赖中介者对象

示例:

同事 功能接口:

type Colleague interface {
	Start()
}

具体同事类:

具体同事类1:

type ConcreteColleague1 struct {
	mediator ConcreteMediator
}

func (this ConcreteColleague1) Start() {
	fmt.Println("============ Start ... ============")
	fmt.Println("============ ConcreteColleague1 Start ============")
	this.Action1()
}

func (this ConcreteColleague1) Action1() {
	fmt.Println("============ ConcreteColleague1 do Action1 ============")
	this.mediator.RecieveMessage(0, "colleague2")
}

func NewConcreteColleague1(mediator ConcreteMediator) *ConcreteColleague1 {
	return &ConcreteColleague1{
		mediator: mediator,
	}
}

具体同事类2:

type ConcreteColleague2 struct {
	mediator ConcreteMediator
}

func (this ConcreteColleague2) Start() {
	fmt.Println("============ ConcreteColleague2 Start ============")
	this.Action21()
}

func (this ConcreteColleague2) Action21() {
	fmt.Println("============ ConcreteColleague2 do Action2 ============")
	this.mediator.RecieveMessage(0, "colleague3")
}

func (this ConcreteColleague2) Action22() {
	fmt.Println("============ ConcreteColleague2 do Action2 ============")
	fmt.Println("============ Happy End ! ============")
}

func NewConcreteColleague2(mediator ConcreteMediator) *ConcreteColleague2 {
	return &ConcreteColleague2{
		mediator: mediator,
	}
}

具体同事类3:

type ConcreteColleague3 struct {
	mediator ConcreteMediator
}

func (this ConcreteColleague3) Start() {
	fmt.Println("============ ConcreteColleague3 Start ============")
	this.Action3()
}

func (this ConcreteColleague3) Action3() {
	fmt.Println("============ ConcreteColleague3 do Action3 ============")
	this.mediator.RecieveMessage(1, "colleague2")
}

func NewConcreteColleague3(mediator ConcreteMediator) *ConcreteColleague3 {
	return &ConcreteColleague3{
		mediator: mediator,
	}
}

中介者 功能接口:

type Mediator interface {
	Register(colleagueName string, colleague Colleague)
	RecieveMessage(stateChange int64, colleagueName string)
}

具体 中介者:

type ConcreteMediator struct {
	ColleagueMap map[string]interface{}
}

func (this *ConcreteMediator) Register(colleagueName string, colleague Colleague) {
	this.ColleagueMap[colleagueName] = colleague
}

func (this *ConcreteMediator) RecieveMessage(stateChange int64, colleagueName string) {
	colleague := this.ColleagueMap[colleagueName]
	//fmt.Println("jinlaile")
	switch colleagueType := colleague.(type) {
	case *ConcreteColleague1:
		colleagueType.Start()
	case *ConcreteColleague2:
		if stateChange == 0 {
			colleagueType.Start()
		} else {
			colleagueType.Action22()
		}
	case *ConcreteColleague3:
		colleagueType.Start()
	}
}

func NewConcreteMediator() ConcreteMediator {
	return ConcreteMediator{
		ColleagueMap: map[string]interface{}{},
	}
}

测试:

package main

import "DemoProject/design/base23/mediator" // 根据自己的项目路径定制

func main() {
	// mediator
	theMediator := mediator.NewConcreteMediator()

	colleague1 := mediator.NewConcreteColleague1(theMediator)
	theMediator.Register("colleague1", colleague1)
	colleague2 := mediator.NewConcreteColleague2(theMediator)
	theMediator.Register("colleague2", colleague2)
	colleague3 := mediator.NewConcreteColleague3(theMediator)
	theMediator.Register("colleague3", colleague3)

	colleague1.Start()
}

注意事项:

  1. 多个类 相互耦合,会形成 网状结构,使用 中介者模式网状结构 分离为 星型结构,进行 解耦
  2. 减少类间依赖,降低了耦合,符合迪米特原则
  3. 中介者承担了较多的责任,一旦 中介者出现了问题整个系统就会受到影响
    如果设计不当,中介者对象本身变得过于复杂,这点在实际使用时,要特别注意
  4. 不同中介者,可以实现 不同的中介逻辑
posted @ 2021-12-14 08:45  在下右转,有何贵干  阅读(94)  评论(0)    收藏  举报