Go语言设计模式实战:中介者模式详解

文章目录

在软件开发中,设计模式是提高代码质量、可维护性和可扩展性的重要工具。中介者模式作为一种行为型设计模式,允许不同类之间通过中介对象进行通信,减少了类之间的直接依赖,从而实现了解耦。本文将深入探讨中介者模式在 Go 语言中的实际应用,通过模拟火车调度的案例,展示这一模式如何在复杂的交互中提供简洁高效的解决方案。

👉 点击查看《Go语言设计模式实战》系列文章目录

《Go语言设计模式实战》以 Go 语言为示例,详细解读编程开发中常见设计模式的实现,涵盖创建型、结构型和行为型设计模式。每篇文章通过具体的 Go 代码展示模式的实际应用,帮助读者深入理解设计模式的核心原理及其在软件开发中的最佳实践。以下是该系列文章的全部内容:

  1. Go语言设计模式实战:单例模式详解
  2. Go语言设计模式实战:原型模式详解
  3. Go语言设计模式实战:工厂方法模式详解
  4. Go语言设计模式实战:建造者模式详解
  5. Go语言设计模式实战:建造者模式详解
  6. Go语言设计模式实战:抽象工厂模式详解
  7. Go语言设计模式实战:享元模式详解
  8. Go语言设计模式实战:代理模式详解
  9. Go语言设计模式实战:外观模式详解
  10. Go语言设计模式实战:桥接模式详解
  11. Go语言设计模式实战:组合模式详解
  12. Go语言设计模式实战:装饰模式详解
  13. Go语言设计模式实战:适配器模式详解
  14. Go语言设计模式实战:责任链模式详解
  15. Go语言设计模式实战:中介者模式详解
  16. Go语言设计模式实战:命令模式详解
  17. Go语言设计模式实战:迭代器模式详解
  18. Go语言设计模式实战:备忘录模式详解
  19. Go语言设计模式实战:状态模式详解
  20. Go语言设计模式实战:观察者模式详解
  21. Go语言设计模式实战:模板方法模式详解
  22. Go语言设计模式实战:策略模式详解
  23. Go语言设计模式实战:访问者模式详解
Golang设计模式实战

什么是中介者模式?

中介者(Mediator)模式是一种行为型设计模式,其核心思想是通过引入一个中介对象来管理不同类之间的通信,从而减少类之间的直接依赖,实现解耦。该模式尤其适用于需要多个类之间进行复杂交互的场景,能够有效提高系统的可维护性和扩展性。

中介者模式的实际应用案例

以老式小火车站为例,为了确保铁路系统的稳定运行,通常两列火车不会直接通信,而是通过车站管理员进行调度。车站管理员充当了中介者的角色,维护着火车进站的调度表。一次只允许一列火车停靠,前一列火车离开后,管理员会通知下一列火车进站。这种模式有效避免了火车之间的直接依赖,确保了调度的高效与安全。

Golang 实现中介者模式

下面的 Golang 代码示例展示了如何在 Go 语言中实现中介者模式,以模拟小火车站管理员调度火车的过程。

package main

import (
	"fmt"
	"sync"
)

// 火车类
type Train struct {
	number   string
	mediator *Mediator
}

// 请求进站
func (t *Train) RequestGetIn() {
	fmt.Println(t.number + "请求进站")
	if t.mediator.canGetIn(t) {
		fmt.Println("mediator:" + t.number + "可以进站停靠")
	} else {
		fmt.Println("mediator:" + t.number + "不能进站,请等待通知")
	}
}

// 出站
func (t *Train) Departure() {
	fmt.Println(t.number + "出站")
	// 中介者通知其他火车可以进站了
	t.mediator.notifyFree()
}

// 进站
func (t *Train) GetIn() {
	fmt.Println(t.number + "已进站")
}

// 中介者类
type Mediator struct {
	isPlatformFree bool
	lock           *sync.Mutex
	trainQueue     []Train
}

// 创建中介者
func newMediator() *Mediator {
	return &Mediator{
		isPlatformFree: true,
		lock:           &sync.Mutex{},
	}
}

// 判断火车能否进站
func (m *Mediator) canGetIn(t *Train) bool {
	m.lock.Lock()
	defer m.lock.Unlock()
	if m.isPlatformFree {
		m.isPlatformFree = false
		return true
	}
	m.trainQueue = append(m.trainQueue, *t)
	return false
}

// 通知火车进站
func (m *Mediator) notifyFree() {
	m.lock.Lock()
	defer m.lock.Unlock()
	if !m.isPlatformFree {
		m.isPlatformFree = true
		fmt.Println("mediator:" + "站台已空闲")
	}
	if len(m.trainQueue) > 0 {
		firstTrainInQueue := m.trainQueue[0]
		m.trainQueue = m.trainQueue[1:]

		fmt.Println("mediator:" + "允许排队中的火车进站")
		firstTrainInQueue.GetIn()
	}
}

func main() {
	m := newMediator()

	// 火车 K6801
	K6801 := Train{
		number:   "K6801",
		mediator: m,
	}

	// 火车 K6308
	K6308 := Train{
		number:   "K6308",
		mediator: m,
	}

	K6308.RequestGetIn()
	K6801.RequestGetIn()
	K6308.Departure()
}

通过运行上述代码,可以看到输出如下:

K6308请求进站
mediator:K6308可以进站停靠
K6801请求进站
mediator:K6801不能进站,请等待通知
K6308出站
mediator:站台已空闲
mediator:允许排队中的火车进站
K6801已进站

从输出结果可以看出,火车 K6308 首先请求进站,得到批准后顺利进站;而火车 K6801 则需要等待 K6308 离开后才能进入。这种调度方式有效防止了火车之间的直接冲突,展示了中介者模式在实际应用中的优势。

中介者模式的优势

  • 降低耦合性:中介者模式通过将复杂的交互行为集中在一个中介者中,从而降低了各个类之间的耦合性。
  • 便于扩展:新增功能时,只需在中介者中添加相应逻辑,而不必对已有类进行修改,符合开闭原则。
  • 提高可维护性:中介者集中管理通信,简化了类之间的交互,使得系统更容易维护。

总结

中介者模式是设计模式中一个非常实用的模式,特别适用于需要协调多个对象间复杂交互的场景。通过本文的案例和代码示例,能够清晰理解中介者模式的基本原理及其实现方式,为今后在项目中使用该模式提供了参考。


也可以看看