Design Patterns(十八):Mediator Pattern--VB代码
★★☆☆☆
用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.
结构图

角色
- 中介者(Mediator)角色:定义一个接口用于各同事对象间的通信。
- 具体中介者(Concrete Mediator)角色:具体中介者通过协调各同事对象实现协作行为,并了解和维护它的各个同事。
- 同事(Colleague)角色:。每一个同事角色都知道对应的具体中介者角色,而且与其他同事角色通信的时候,一定要通过中介者角色协作。
动机
在软件构建过程中,经常会出现多个对象互相关联交互的情况,对象之间常常会维持一种复杂的引用关系,如果遇到一些需求的更改,这种直接的引用关系将面临不断的变化。
在这种情况下,我们可使用一个“中介对象”来管理对象间的关联关系,避免相互交互的对象之间的紧耦合引用关系,从而更好地抵御变化。
意图
用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
示意性代码


'Mainapp test application
Module MainApp
Public Sub Main()
Dim m As New ConcreteMediator
Dim c1 As New ConcreteColleague1(m)
Dim c2 As New ConcreteColleague2(m)
m.Colleague1 = c1
m.Colleague2 = c2
c1.Send("How are you?")
c2.Send("I'm fine.")
'Wait for user
Console.ReadLine()
End Sub
End Module
'"Mediator"
Public MustInherit Class Mediator
Public MustOverride Sub Send(ByVal c As Colleague, ByVal message As String)
End Class
'"ConcreteMediator"
Public Class ConcreteMediator
Inherits Mediator
Private _colleague1 As ConcreteColleague1
Private _colleague2 As ConcreteColleague2
Public WriteOnly Property Colleague1() As ConcreteColleague1
Set(ByVal value As ConcreteColleague1)
Me._colleague1 = value
End Set
End Property
Public WriteOnly Property Colleague2() As ConcreteColleague2
Set(ByVal value As ConcreteColleague2)
Me._colleague2 = value
End Set
End Property
Public Overrides Sub Send(ByVal c As Colleague, ByVal message As String)
If TypeOf c Is ConcreteColleague1 Then
_colleague2.Notify(message)
Else
_colleague1.Notify(message)
End If
End Sub
End Class
'"Colleague"
Public MustInherit Class Colleague
Protected _mediator As Mediator
'Constructor
Public Sub New(ByVal mediator As Mediator)
Me._mediator = mediator
End Sub
End Class
'"ConcreteColleague1"
Public Class ConcreteColleague1
Inherits Colleague
'Constructor
Public Sub New(ByVal mediator As Mediator)
MyBase.New(mediator)
End Sub
Public Sub Send(ByVal message As String)
Console.WriteLine("Colleague1 sends message: " & message)
_mediator.Send(Me, message)
End Sub
Public Sub Notify(ByVal message As String)
Console.WriteLine("Colleague1 gets message: " & message)
End Sub
End Class
'"ConcreteColleague2"
Public Class ConcreteColleague2
Inherits Colleague
'Constructor
Public Sub New(ByVal mediator As Mediator)
MyBase.new(mediator)
End Sub
Public Sub Send(ByVal message As String)
Console.WriteLine("Colleague2 sends message: " & message)
_mediator.Send(Me, message)
End Sub
Public Sub Notify(ByVal message As String)
Console.WriteLine("Colleague2 gets message: " & message)
End Sub
End Class
一个实例
在下面的示例中,实现一个布告栏式的ChatRoom,任何人想要发送消息给其他人,只需将消息发送给ChatRoom对象,由ChatRoom负责数据的转发,而不是直接与消息的接收者交互。


'MainApp test application
Module MainApp
Public Sub Main()
'Create chatroom
Dim chatroom As New Chatroom
'Create participants and register them
Dim George As Participant = New Beatle("George")
Dim Paul As Participant = New Beatle("Paul")
Dim Ringo As Participant = New Beatle("Ringo")
Dim John As Participant = New Beatle("John")
Dim Yoko As Participant = New NonBeatle("Yoko")
chatroom.Register(George)
chatroom.Register(Paul)
chatroom.Register(Ringo)
chatroom.Register(John)
chatroom.Register(Yoko)
'Chatting participants
Yoko.Send("John", "Hi John!")
Paul.Send("Ringo", "All you need is love")
Ringo.Send("George", "My sweet Lord")
Paul.Send("John", "Can't buy me love")
John.Send("Yoko", "My sweet love")
'Wait for user
Console.ReadLine()
End Sub
End Module
'"Mediator"
Public MustInherit Class AbstractChatroom
Public MustOverride Sub Register(ByVal participant As Participant)
Public MustOverride Sub Send( _
ByVal from As String, ByVal [to] As String, ByVal message As String)
End Class
'"ConcreteMediator"
Public Class Chatroom
Inherits AbstractChatroom
Private participants As New Dictionary(Of String, Participant)
Public Overrides Sub Register(ByVal participant As Participant)
If Not participants.ContainsKey(participant.Name) Then
participants(participant.Name) = participant
End If
participant.Chatroom = Me
End Sub
Public Overrides Sub Send( _
ByVal from As String, ByVal [to] As String, ByVal message As String)
Dim pto As Participant = participants([to])
If pto IsNot Nothing Then
pto.Receive(from, message)
End If
End Sub
End Class
'"AbstractColleague"
Public Class Participant
Private _chatroom As Chatroom
Private _name As String
'Constructor
Public Sub New(ByVal name As String)
Me._name = name
End Sub
Public ReadOnly Property Name() As String
Get
Return _name
End Get
End Property
Public Property Chatroom() As Chatroom
Set(ByVal value As Chatroom)
_chatroom = value
End Set
Get
Return _chatroom
End Get
End Property
Public Sub Send(ByVal [to] As String, ByVal message As String)
_chatroom.Send(Name, [to], message)
End Sub
Public Overridable Sub Receive(ByVal from As String, ByVal message As String)
Console.WriteLine("{0} to {1}: '{2}'", _
from, _name, message)
End Sub
End Class
'" ConcreteColleague1"
Public Class Beatle
Inherits Participant
'Constructor
Public Sub New(ByVal name As String)
MyBase.new(name)
End Sub
Public Overrides Sub Receive(ByVal from As String, ByVal message As String)
Console.Write("To a Beatle: ")
MyBase.Receive(from, message)
End Sub
End Class
'" ConcreteColleague2"
Public Class NonBeatle
Inherits Participant
'Constructor
Public Sub New(ByVal name As String)
MyBase.new(name)
End Sub
Public Overrides Sub Receive(ByVal from As String, ByVal message As String)
Console.Write("To a Non-Beatle: ")
MyBase.Receive(from, message)
End Sub
End Class
Mediator Pattern模式的几个要点:
1、将多个对象间复杂的关联关系解耦,Mediator模式将多个对象间的控制逻辑进行集中管理,变“多个对象互相关联”为“多个对象和一个中介者关联”,简化了系统的维护,抵御了可能的变化。
2、随着控制逻辑的复杂化,Mediator具体对象的实现可能相当复杂。这时候可以对Mediator对象进行分解处理。
3、Facade模式是解耦系统外到系统内(单向)的对象关联关系;Mediator模式是解耦系统内各个对象之间(双向)的关联关系。
我的理解
封装对象间的交互,支持对象交互的变化。
参考资料
《C#面向对象设计模式纵横谈系列课程(17)》 李建中老师
分类:
Design Pattern
随笔分类 (333)
Cnblogs's
Front End
Oracle's
Software's
- Apache HTTP Server
- CodeSmith Community
- Grapecity(FAQ)
- Mybase
- ClubFarPoint(Forum)
- Beyond Compare
- CrystalReport(FAQ)
- 秀丸
- Software Advice
- Software: Business & Nonprofit | Reviews and Top Software at Capterra
- Capterra
- Business Software Reviews from Software Advice
Copyright © 2025 sekihin
Powered by .NET 9.0 on Kubernetes
Powered by .NET 9.0 on Kubernetes
![]() | 本作品采用 知识共享署名-非商业性使用 2.5 中国大陆许可协议进行许可。 |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通