Go设计模式(28)-中介者模式

简介: 中介者模式是设计模式系列中最后一个模式。这个模式我从未用过,主要原因是没碰到过合适的场景。如果大家有适合使用中介者模式的场景,中介者模式能帮大家更好的维护系统。

中介者模式是设计模式系列中最后一个模式。这个模式我从未用过,主要原因是没碰到过合适的场景。如果大家有适合使用中介者模式的场景,中介者模式能帮大家更好的维护系统。

UML类图位置:https://www.processon.com/view/link/60d29bf3e401fd49502afd25

本文代码链接为:https://github.com/shidawuhen/asap/blob/master/controller/design/28mediator.go

1.定义

1.1中介者模式

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

UML:

图片

1.2分析

对于定义,大家比较容易理解。由中介者控制所有的交互,Colleague对象无需相互感知。

使用中介者模式有个前提,Colleague之间相互影响,即一个Colleague的变化会影响其它Colleague。

我们再来看UML。通过UML可以看出

  • Mediator包含所有Colleague,这是中介者能控制所有交互的基础
  • Colleague包含Mediator,Colleague变化可直接通知Mediator,这是Colleague无需知道其它Colleague的基础,只需知道Mediator即可

根据前面提到的前提和UML类图,我们思考的再深一些,ConcreteColleague是否有相同父类并不重要,只要Mediator包含所有ConcreteColleague,ConcreteColleague有Mediator,中介者模式依然有效。

2.应用场景

使用中介者模式有哪些好处?

我们设想一种场景,假设有多个Colleague,分别为Colleague1、Colleague2、Colleague3、Colleague4,如果一个Colleague的动作会影响到其它Colleague,便形成多对多的网状结构,随着Colleague增加,会更加难以管理。如果使用中介者模式,会变成一对多的星状结构,所有Colleague只和Mediator相关,管理复杂度降低。

在实际工作中,没碰到过网状结构,所以没用过中介者模式。比较合适的例子,如GoLand中的注册,点击Active Goland/Evaluate for free,会显示不同的UI组件。

图片

图片

3.代码实现


我们简单实现GoLand激活的例子。

package main

import "fmt"

/**
 * @Author: Jason Pang
 * @Description: 中介者接口
 */
type Mediator interface {
  Process(colleague UIColleague)
}

/**
 * @Author: Jason Pang
 * @Description: 真正的中介者
 */
type UIMediator struct {
  activate *ActivateColleague
  evaluate *EvaluateColleague
  text     *TextColleague
}

/**
 * @Author: Jason Pang
 * @Description: 中介者大总管,处理所有事情
 * @receiver u
 */
func (u *UIMediator) Process(colleague UIColleague) {
  if colleague == u.activate { //如果是激活
    u.evaluate.Show("试用内容隐藏")
    u.text.Show("请输入激活码")
  } else if colleague == u.evaluate { //如果是试用
    u.activate.Show("激活内容隐藏")
    u.text.Show("请出入激活时间")
  }
}

/**
 * @Author: Jason Pang
 * @Description: Colleague接口
 */
type UIColleague interface {
  Action()
}

/**
 * @Author: Jason Pang
 * @Description: 激活UI
 */
type ActivateColleague struct {
  mediator Mediator
}

/**
 * @Author: Jason Pang
 * @Description: 激活触发的动作
 * @receiver a
 */
func (a *ActivateColleague) Action() {
  a.mediator.Process(a)
}

/**
 * @Author: Jason Pang
 * @Description: 激活UI显示内容
 * @receiver e
 * @param text
 */
func (e *ActivateColleague) Show(text string) {
  fmt.Println(text)
}

/**
 * @Author: Jason Pang
 * @Description: 试用UI
 */
type EvaluateColleague struct {
  mediator Mediator
}

/**
 * @Author: Jason Pang
 * @Description: 试用触发的动作
 * @receiver e
 */
func (e *EvaluateColleague) Action() {
  e.mediator.Process(e)
}

/**
 * @Author: Jason Pang
 * @Description: 试用UI显示内容
 * @receiver e
 * @param text
 */
func (e *EvaluateColleague) Show(text string) {
  fmt.Println(text)
}

/**
 * @Author: Jason Pang
 * @Description: 文案UI
 */
type TextColleague struct {
  mediator Mediator
}

/**
 * @Author: Jason Pang
 * @Description: 文案触发动作
 * @receiver t
 */
func (t *TextColleague) Action() {
  t.mediator.Process(t)
}

/**
 * @Author: Jason Pang
 * @Description: 文案显示内容
 * @receiver t
 * @param text
 */
func (t *TextColleague) Show(text string) {
  fmt.Println(text)
}

func main() {
  //初始化
  m := &UIMediator{}

  activate := &ActivateColleague{
    mediator: m,
  }
  evaluate := &EvaluateColleague{
    mediator: m,
  }
  text := &TextColleague{
    mediator: m,
  }

  m.activate = activate
  m.evaluate = evaluate
  m.text = text
  //点击激活
  fmt.Println("-----------------点击激活")
  activate.Action()
  //点击试用
  fmt.Println("-----------------点击试用")
  evaluate.Action()
}

输出:

-----------------点击激活

试用内容隐藏

请输入激活码

-----------------点击试用

激活内容隐藏

请出入激活时间

从代码中可以看出,Mediator有所有的UI,UI只调用Mediator,无需知道其它UI,Mediator通过Process处理所有操作。当今后增加新UI,只需Mediator知道即可,不必改动其它UI。当然,要防止Mediator变成超级大类,这需要根据实际情况做取舍。

总结

中介者模式算是聚而歼之的模式,因为从分而治之上讲,对应的操作应该让每一个Colleague自行管理,但这样做,Colleague之间需要相互了解,沟通成本太高。

如果收拢到Mediator,整体效率会高很多,但Mediator存在成为上帝类的可能,反而导致不好维护。

这是不是特别像实际生活。所以说世上的处理方案没有定法,能够更好的解决问题就是最好的。共勉。

最后

大家如果喜欢我的文章,可以关注我的公众号(程序员麻辣烫)

我的个人博客为:https://shidawuhen.github.io/

往期文章回顾:

  1. 设计模式
  2. 招聘
  3. 思考
  4. 存储
  5. 算法系列
  6. 读书笔记
  7. 小工具
  8. 架构
  9. 网络
  10. Go语言
相关文章
|
2月前
|
设计模式 Java
Java设计模式-中介者模式(20)
Java设计模式-中介者模式(20)
|
3月前
|
设计模式 前端开发 Java
【十三】设计模式~~~行为型模式~~~中介者模式(Java)
文章详细介绍了中介者模式(Mediator Pattern),这是一种对象行为型模式,用于封装一系列对象的交互,降低系统耦合度,并简化对象之间的交互关系。通过案例分析、结构图、时序图和代码示例,文章展示了中介者模式的组成部分、实现方式和应用场景,并讨论了其优点、缺点和适用情况。
【十三】设计模式~~~行为型模式~~~中介者模式(Java)
|
3月前
|
设计模式 Go
go 设计模式之观察者模式
go 设计模式之观察者模式
|
4月前
|
设计模式 Go
Go语言设计模式:使用Option模式简化类的初始化
在Go语言中,面对构造函数参数过多导致的复杂性问题,可以采用Option模式。Option模式通过函数选项提供灵活的配置,增强了构造函数的可读性和可扩展性。以`Foo`为例,通过定义如`WithName`、`WithAge`、`WithDB`等设置器函数,调用者可以选择性地传递所需参数,避免了记忆参数顺序和类型。这种模式提升了代码的维护性和灵活性,特别是在处理多配置场景时。
72 8
|
3月前
|
设计模式 监控 Go
|
4月前
|
设计模式 JavaScript
js设计模式【详解】—— 中介者模式
js设计模式【详解】—— 中介者模式
66 5
|
5月前
|
设计模式
中介者模式-大话设计模式
中介者模式-大话设计模式
|
5月前
|
设计模式 Java 程序员
Java设计模式之中介者模式详解
Java设计模式之中介者模式详解
|
5月前
|
设计模式
设计模式之中介者模式
设计模式之中介者模式
|
5月前
|
设计模式 前端开发 NoSQL
设计模式第八讲:观察者模式和中介者模式详解
 定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。中介者模式又叫调停模式,它是迪米特法则的典型应用。
211 0