设计模式笔记 - 中介者模式

124 阅读2分钟

中介者模式是一种行为设计模式,能让你减少对象之间混乱无序的依赖关系。该模式会限制对象之间的直接交互,迫使它们通过一个中介者对象进行合作。


解决什么问题?

  • 当一些对象和其他对象紧密耦合以致难以对其进行修改时,可使用中介者模式。
  • 当组件因过于依赖其他组件而无法在不同应用中复用时,可使用中介者模式。
  • 如果为了能在不同情景下复用一些基本行为,导致你需要被迫创建大量组件子类时,可使用中介者模式。

优势:

  • 单一职责原则。 你可以将多个组件间的交流抽取到同一位置, 使其更易于理解和维护。
  • 开闭原则。 你无需修改实际组件就能增加新的中介者。
  • 你可以减轻应用中多个组件间的耦合情况。
  • 你可以更方便地复用各个组件。

劣势:

  • 一段时间后,中介者可能会演化成为上帝对象。
  • 关联的组件过多,中介者类的逻辑可能很复杂。

实现步骤:

  • 定义中介者接口
  • 实体中介者类实现接口,关联各个实体组件类
  • 各个实体组件类将上下文发送到中介者类进行转发处理

下面是实现代码:

package main

import "fmt"

type gui interface{}

type mediator interface {
	notify(gui)
}

type guiMediator struct {
	btn      *button
	username *entry
	passwd   *entry
	sbar     *statubar
}

func (g *guiMediator) notify(gi gui) {
	if _, ok := gi.(*button); ok {
		if g.username.content != "jack" || g.passwd.content != "123" {
			g.sbar.showText("username or passwd invalid")
		} else {
			g.sbar.showText("permit access")
		}
	}

	if _, ok := gi.(*entry); ok {
		msg := fmt.Sprintf("username: %s, passwd: %s",
			g.username.content, g.passwd.content)
		g.sbar.showText(msg)
	}
}

type button struct {
	m mediator
	gui
}

func (b *button) clicked() {
	b.m.notify(b)
}

type entry struct {
	m       mediator
	content string
	gui
}

func (e *entry) changed() {
	e.m.notify(e)
}

type statubar struct {
	m mediator
	gui
}

func (s *statubar) showText(text string) {
	fmt.Println("statubar show text:", text)
}

func main() {
	m := &guiMediator{}

	btn := button{m: m}
	username := entry{m: m, content: "jack"}
	passwd := entry{m: m, content: "123"}
	bar := statubar{m: m}

	m.btn = &btn
	m.username = &username
	m.passwd = &passwd
	m.sbar = &bar

	btn.clicked()

	username.content = "hacker"
	username.changed()
	btn.clicked()
}

输出:

statubar show text: permit access
statubar show text: username: hacker, passwd: 123
statubar show text: username or passwd invalid

参考