中介者模式是一种行为设计模式,能让你减少对象之间混乱无序的依赖关系。该模式会限制对象之间的直接交互,迫使它们通过一个中介者对象进行合作。
解决什么问题?
- 当一些对象和其他对象紧密耦合以致难以对其进行修改时,可使用中介者模式。
- 当组件因过于依赖其他组件而无法在不同应用中复用时,可使用中介者模式。
- 如果为了能在不同情景下复用一些基本行为,导致你需要被迫创建大量组件子类时,可使用中介者模式。
优势:
- 单一职责原则。 你可以将多个组件间的交流抽取到同一位置, 使其更易于理解和维护。
- 开闭原则。 你无需修改实际组件就能增加新的中介者。
- 你可以减轻应用中多个组件间的耦合情况。
- 你可以更方便地复用各个组件。
劣势:
- 一段时间后,中介者可能会演化成为上帝对象。
- 关联的组件过多,中介者类的逻辑可能很复杂。
实现步骤:
- 定义
中介者接口 实体中介者类实现接口,关联各个实体组件类- 各个
实体组件类将上下文发送到中介者类进行转发处理
下面是实现代码:
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