中介者模式
让多个对象不再“互相通知”,而是都交给“中介者”去协调消息和命令
“大家都找老大,老大来指挥”!
适合的场景
系统中多个对象之间关系复杂、交互频繁
对象之间直接引用彼此导致强耦合,修改一个就要改一堆
想要把对象之间的“通信逻辑”集中管理,让每个对象专注于自己的本职工作
比如 UI 按钮控制输入框状态、聊天室中的多个用户都通过服务器中介通信,或者是角色状态机里不同模块之间解耦交互~都会用到它
基本结构
Mediator中介者接口ConcreteMediator具体中介者,实现协调逻辑Colleague同事对象,持有对中介者的引用,只跟中介者通信
示例
C# 聊天系统
csharp
// 中介者接口
interface IChatMediator
{
void SendMessage(string message, User user);
}
// 具体中介者
class ChatRoom : IChatMediator
{
private List<User> users = new();
public void Register(User user)
{
users.Add(user);
}
public void SendMessage(string message, User sender)
{
foreach (var user in users)
{
if (user != sender)
{
user.Receive(message);
}
}
}
}
// 同事类
class User
{
private readonly string _name;
private readonly IChatMediator _mediator;
public User(string name, IChatMediator mediator)
{
_name = name;
_mediator = mediator;
}
public void Send(string message)
{
Console.WriteLine($"{_name} 发送: {message}");
_mediator.SendMessage(message, this);
}
public void Receive(string message)
{
Console.WriteLine($"{_name} 收到: {message}");
}
}
// 使用
var chatRoom = new ChatRoom();
var inabaMeguru= new User("Inaba Meguru", chatRoom);
var ayachiNene= new User("Ayachi Nene", chatRoom);
chatRoom.Register(inabaMeguru);
chatRoom.Register(ayachiNene);
inabaMeguru.Send("Ciallo~(∠・▽< )⌒☆");GDScript示例
UI控件中介
gdscript
class Mediator:
func notify(sender: Node, event: String) -> void:
pass
class DialogMediator extends Mediator:
var button_close
var label_info
func _init(close_btn: Button, label: Label):
button_close = close_btn
label_info = label
func notify(sender: Node, event: String) -> void:
if sender == button_close and event == "click":
label_info.text = "按钮被禁用"
button_close.disabled = true
# 使用时
func _ready():
var cloneButton := Button.new()
cloneButton.size = Vector2(128, 128)
cloneButton.text = "点我"
add_child(cloneButton)
var infoLabel := Label.new()
infoLabel.text = "点击禁用按钮"
add_child(infoLabel)
var mediator = DialogMediator.new(cloneButton, infoLabel)
cloneButton.pressed.connect(func(): mediator.notify(cloneButton, "click"))