当前位置: 代码网 > it编程>编程语言>Asp.net > C#和Unity中的中介者模式使用方式

C#和Unity中的中介者模式使用方式

2025年08月14日 Asp.net 我要评论
c#中的中介者模式详解中介者模式(mediator pattern)是一种行为设计模式,它能减少对象之间混乱无序的依赖关系,通过引入一个中介者对象来封装一系列对象之间的交互。一、中介者模式的基本概念1

c#中的中介者模式详解

中介者模式(mediator pattern)是一种行为设计模式,它能减少对象之间混乱无序的依赖关系,通过引入一个中介者对象来封装一系列对象之间的交互。

一、中介者模式的基本概念

1. 定义

中介者模式定义了一个对象来封装一组对象之间的交互方式,使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

2. 组成要素

  • mediator(中介者接口) :定义各个同事对象通信的接口
  • concretemediator(具体中介者) :实现中介者接口,协调各同事对象的交互
  • colleague(同事类) :每个同事对象都知道它的中介者对象,与其他同事通信时都通过中介者

3. 模式结构

[同事a] ────> [中介者] <─── [同事b]
    ↑____________|____________↑

二、中介者模式的特点

1. 优点

  • 降低耦合度:将对象之间的网状结构变为星型结构
  • 集中控制:将交互复杂性集中到中介者中
  • 简化对象协议:用一对多的交互代替多对多的交互
  • 易于扩展:新增同事类只需修改中介者或新增具体中介者

2. 缺点

  • 中介者可能变得复杂:如果同事类过多,中介者会变得庞大复杂
  • 过度集中化:中介者集中了太多控制逻辑,可能成为"上帝对象"

三、中介者模式的实现方式

1. 基本实现

// 中介者接口
public interface imediator
{
    void notify(object sender, string ev);
}

// 基础同事类
public abstract class colleague
{
    protected imediator _mediator;

    public colleague(imediator mediator)
    {
        _mediator = mediator;
    }
}

// 具体同事a
public class concretecolleaguea : colleague
{
    public concretecolleaguea(imediator mediator) : base(mediator) { }

    public void doa()
    {
        console.writeline("colleaguea does a.");
        _mediator.notify(this, "a");
    }

    public void dob()
    {
        console.writeline("colleaguea does b.");
    }
}

// 具体同事b
public class concretecolleagueb : colleague
{
    public concretecolleagueb(imediator mediator) : base(mediator) { }

    public void doc()
    {
        console.writeline("colleagueb does c.");
        _mediator.notify(this, "c");
    }

    public void dod()
    {
        console.writeline("colleagueb does d.");
    }
}

// 具体中介者
public class concretemediator : imediator
{
    private concretecolleaguea _colleaguea;
    private concretecolleagueb _colleagueb;

    public concretecolleaguea colleaguea
    {
        set { _colleaguea = value; }
    }

    public concretecolleagueb colleagueb
    {
        set { _colleagueb = value; }
    }

    public void notify(object sender, string ev)
    {
        if (ev == "a")
        {
            console.writeline("mediator reacts on a and triggers:");
            _colleagueb.doc();
        }
  
        if (ev == "c")
        {
            console.writeline("mediator reacts on c and triggers:");
            _colleaguea.dob();
            _colleagueb.dod();
        }
    }
}

2. 使用示例

// 客户端代码
var mediator = new concretemediator();
var colleaguea = new concretecolleaguea(mediator);
var colleagueb = new concretecolleagueb(mediator);

mediator.colleaguea = colleaguea;
mediator.colleagueb = colleagueb;

console.writeline("client triggers operation a.");
colleaguea.doa();

console.writeline();

console.writeline("client triggers operation c.");
colleagueb.doc();

3. 更复杂的实现(聊天室示例)

// 中介者接口
public interface ichatroom
{
    void register(participant participant);
    void send(string from, string to, string message);
}

// 具体中介者 - 聊天室
public class chatroom : ichatroom
{
    private dictionary<string, participant> _participants = new dictionary<string, participant>();

    public void register(participant participant)
    {
        if (!_participants.containskey(participant.name))
        {
            _participants.add(participant.name, participant);
        }
        participant.chatroom = this;
    }

    public void send(string from, string to, string message)
    {
        if (_participants.trygetvalue(to, out var participant))
        {
            participant.receive(from, message);
        }
    }
}

// 同事基类
public abstract class participant
{
    public string name { get; }
    public ichatroom chatroom { get; set; }

    protected participant(string name)
    {
        name = name;
    }

    public void send(string to, string message)
    {
        chatroom.send(name, to, message);
    }

    public abstract void receive(string from, string message);
}

// 具体同事类
public class user : participant
{
    public user(string name) : base(name) { }

    public override void receive(string from, string message)
    {
        console.writeline($"{from} to {name}: '{message}'");
    }
}

// 使用
var chatroom = new chatroom();

var john = new user("john");
var jane = new user("jane");

chatroom.register(john);
chatroom.register(jane);

john.send("jane", "hi jane!");
jane.send("john", "hello john!");

四、中介者模式的使用场景

1. 典型使用场景

  1. 对象间存在复杂的引用关系:当系统中对象之间存在复杂的网状引用关系,导致系统结构混乱且难以理解时。
  2. 需要集中控制对象间的交互:当多个类之间有复杂的交互逻辑,且这些逻辑需要集中管理时。
  3. 想定制分布在多个类中的行为:当行为分布在多个类中,但又需要根据需求改变这些行为时。
  4. gui组件交互:图形用户界面中,各种控件(按钮、文本框等)之间的交互。
  5. 消息传递系统:如聊天应用、通知系统等需要多方通信的场景。

2. 实际应用示例

示例1:航空管制系统

// 航空交通管制中介者接口
public interface iairtrafficcontrol
{
    // 注册飞机到管制系统
    void registeraircraft(aircraft aircraft);
  
    // 发送警告消息(发送者飞机 + 消息内容)
    void sendwarningmessage(aircraft sender, string message);
}

// 飞机类(同事类)
public class aircraft
{
    // 飞机呼号(唯一标识)
    public string callsign { get; }
  
    // 持有对航空管制中心(中介者)的引用
    private iairtrafficcontrol _atc;
  
    // 构造函数:初始化飞机并注册到管制系统
    public aircraft(string callsign, iairtrafficcontrol atc)
    {
        callsign = callsign;
        _atc = atc;
        _atc.registeraircraft(this); // 自动注册到管制系统
    }
  
    // 发送警告消息(通过管制中心转发)
    public void sendwarning(string message)
    {
        // 不直接联系其他飞机,而是通过管制中心发送
        _atc.sendwarningmessage(this, message);
    }
  
    // 接收来自其他飞机的警告
    public void receivewarning(string from, string message)
    {
        // 打印接收到的警告信息
        console.writeline($"{callsign} received from {from}: {message}");
    }
}

// 塔台管制中心(具体中介者实现)
public class tower : iairtrafficcontrol
{
    // 保存所有注册的飞机列表
    private list<aircraft> _aircrafts = new list<aircraft>();
  
    // 注册飞机到管制系统
    public void registeraircraft(aircraft aircraft)
    {
        // 防止重复注册
        if (!_aircrafts.contains(aircraft))
        {
            _aircrafts.add(aircraft);
        }
    }
  
    // 处理警告消息转发
    public void sendwarningmessage(aircraft sender, string message)
    {
        // 遍历所有已注册的飞机(排除发送者自己)
        foreach (var aircraft in _aircrafts.where(a => a != sender))
        {
            // 将消息转发给其他飞机
            aircraft.receivewarning(sender.callsign, message);
        }
    }
}

示例2:订单处理系统

// 订单中介者接口
public interface iordermediator
{
    // 通知方法:组件通过此方法与中介者通信
    // sender - 触发事件的组件
    // eventtype - 事件类型标识
    void notify(ordercomponent sender, string eventtype);
}

// 订单组件基类(抽象同事类)
public abstract class ordercomponent
{
    // 持有对中介者的引用
    protected iordermediator _mediator;
  
    // 构造函数:注入中介者实例
    public ordercomponent(iordermediator mediator)
    {
        _mediator = mediator;
    }
}

// 库存系统(具体同事类)
public class inventorysystem : ordercomponent
{
    // 构造函数:调用基类构造函数
    public inventorysystem(iordermediator mediator) : base(mediator) { }
  
    // 检查库存方法
    public void checkstock()
    {
        console.writeline("checking stock...");
        // 通知中介者库存已检查
        _mediator.notify(this, "stockchecked");
    }
  
    // 更新库存方法
    public void updatestock()
    {
        console.writeline("updating stock...");
    }
}

// 支付系统(具体同事类)
public class paymentsystem : ordercomponent
{
    // 构造函数:调用基类构造函数
    public paymentsystem(iordermediator mediator) : base(mediator) { }
  
    // 处理支付方法
    public void processpayment()
    {
        console.writeline("processing payment...");
        // 通知中介者支付已处理
        _mediator.notify(this, "paymentprocessed");
    }
}

// 订单中介者实现(具体中介者)
public class ordermediator : iordermediator
{
    // 持有库存系统引用
    private inventorysystem _inventory;
    // 持有支付系统引用
    private paymentsystem _payment;
  
    // 构造函数:注入需要的组件
    public ordermediator(inventorysystem inventory, paymentsystem payment)
    {
        _inventory = inventory;
        _payment = payment;
    }
  
    // 实现通知处理方法
    public void notify(ordercomponent sender, string eventtype)
    {
        // 如果是库存系统且事件类型为"stockchecked"
        if (sender is inventorysystem && eventtype == "stockchecked")
        {
            // 触发支付系统处理支付
            _payment.processpayment();
        }
        // 如果是支付系统且事件类型为"paymentprocessed"
        else if (sender is paymentsystem && eventtype == "paymentprocessed")
        {
            // 更新库存
            _inventory.updatestock();
            console.writeline("order completed!");
        }
    }
}

五、中介者模式与其他模式的关系

与外观模式的区别

  • 外观模式为子系统提供简化接口,但不添加新功能
  • 中介者模式集中同事对象间的通信,可以添加协调逻辑

与观察者模式的区别

  • 观察者模式通过订阅/发布机制实现单向通信
  • 中介者模式对象间通过中介者进行双向通信

与命令模式结合

  • 可以使用命令模式将请求封装为对象,由中介者管理这些命令

六、最佳实践

合理划分责任

  • 中介者应只负责协调,不承担业务逻辑
  • 避免创建"上帝对象"

考虑使用事件

  • 在c#中可以使用事件机制实现轻量级中介者

适度使用

  • 只在对象间交互确实复杂时使用
  • 简单交互直接引用可能更合适

可测试性设计

  • 使中介者易于替换,方便单元测试

性能考虑

  • 高频交互场景需评估中介者带来的性能影响

七、总结

中介者模式是管理复杂对象交互的强大工具,特别适用于以下场景:

  • 对象间存在大量直接连接
  • 系统组件难以复用
  • 交互逻辑分散难以理解
  • 需要集中控制对象间通信

在c#中实现中介者模式时,可以:

  1. 定义清晰的中介者接口
  2. 使同事类只依赖于中介者
  3. 将复杂的交互逻辑封装在中介者中
  4. 考虑使用事件或委托简化实现

正确使用中介者模式可以显著降低系统复杂度,提高代码的可维护性和灵活性。

八、使用事件或委托简化实现中介者模式

中介者模式可以通过c#的事件和委托机制来简化实现,这种方式可以减少中介者类的复杂性,同时保持对象间的解耦。下面我将展示如何使用事件来重构中介者模式。

1. 基于事件的简化实现

基本架构

// 定义事件参数基类
public abstract class ordereventargs : eventargs
{
    public string eventtype { get; set; }
}

// 库存系统事件参数
public class inventoryeventargs : ordereventargs
{
    public int productid { get; set; }
    public int quantity { get; set; }
}

// 支付系统事件参数
public class paymenteventargs : ordereventargs
{
    public decimal amount { get; set; }
    public string paymentmethod { get; set; }
}

// 订单组件基类(使用事件)
public abstract class ordercomponent
{
    // 定义事件处理器委托
    public delegate void ordereventhandler(object sender, ordereventargs e);
  
    // 组件事件
    public event ordereventhandler onorderevent;
  
    // 触发事件的方法
    protected void raiseevent(ordereventargs e)
    {
        onorderevent?.invoke(this, e);
    }
}

// 库存系统实现
public class inventorysystem : ordercomponent
{
    public void checkstock(int productid)
    {
        console.writeline($"checking stock for product {productid}...");
        raiseevent(new inventoryeventargs {
            eventtype = "stockchecked",
            productid = productid,
            quantity = 100 // 假设检查到有100个库存
        });
    }
  
    public void updatestock(int productid, int quantity)
    {
        console.writeline($"updating stock for product {productid}, quantity: {quantity}");
    }
}

// 支付系统实现
public class paymentsystem : ordercomponent
{
    public void processpayment(decimal amount, string method)
    {
        console.writeline($"processing payment of {amount} via {method}");
        raiseevent(new paymenteventargs {
            eventtype = "paymentprocessed",
            amount = amount,
            paymentmethod = method
        });
    }
}

事件协调器(轻量级中介者)

public class ordereventcoordinator
{
    private readonly inventorysystem _inventory;
    private readonly paymentsystem _payment;
  
    public ordereventcoordinator(inventorysystem inventory, paymentsystem payment)
    {
        _inventory = inventory;
        _payment = payment;
  
        // 订阅库存系统事件
        _inventory.onorderevent += handleinventoryevent;
  
        // 订阅支付系统事件
        _payment.onorderevent += handlepaymentevent;
    }
  
    private void handleinventoryevent(object sender, ordereventargs e)
    {
        if (e is inventoryeventargs args && args.eventtype == "stockchecked")
        {
            // 库存检查完成后处理支付
            _payment.processpayment(99.99m, "creditcard");
        }
    }
  
    private void handlepaymentevent(object sender, ordereventargs e)
    {
        if (e is paymenteventargs args && args.eventtype == "paymentprocessed")
        {
            // 支付完成后更新库存
            _inventory.updatestock(1, -1); // 假设产品id为1,减少1个库存
            console.writeline("order completed!");
        }
    }
}

2. 使用action委托的简化实现

更轻量的实现方式

// 组件基类(使用action委托)
public abstract class ordercomponent
{
    protected action<string, object> mediatorcallback { get; }
  
    public ordercomponent(action<string, object> mediatorcallback)
    {
        mediatorcallback = mediatorcallback;
    }
}

// 库存系统
public class inventorysystem : ordercomponent
{
    public inventorysystem(action<string, object> callback) : base(callback) {}
  
    public void checkstock(int productid)
    {
        console.writeline($"checking stock for product {productid}...");
        mediatorcallback?.invoke("stockchecked", new { productid = productid });
    }
  
    public void updatestock(int productid, int quantity)
    {
        console.writeline($"updating stock for product {productid}, quantity: {quantity}");
    }
}

// 支付系统
public class paymentsystem : ordercomponent
{
    public paymentsystem(action<string, object> callback) : base(callback) {}
  
    public void processpayment(decimal amount, string method)
    {
        console.writeline($"processing payment of {amount} via {method}");
        mediatorcallback?.invoke("paymentprocessed", new { amount = amount, method = method });
    }
}

// 使用lambda表达式作为中介者
public class program
{
    public static void main()
    {
        // 创建支付系统并定义其回调
        var payment = new paymentsystem((eventtype, data) => 
        {
            if (eventtype == "paymentprocessed")
            {
                console.writeline("payment processed callback");
            }
        });
  
        // 创建库存系统并定义完整流程
        var inventory = new inventorysystem((eventtype, data) => 
        {
            dynamic eventdata = data;
      
            if (eventtype == "stockchecked")
            {
                console.writeline($"stock checked for product {eventdata.productid}");
                payment.processpayment(99.99m, "creditcard");
            }
            else if (eventtype == "paymentprocessed")
            {
                inventory.updatestock(1, -1);
                console.writeline("order completed!");
            }
        });
  
        // 启动流程
        inventory.checkstock(1);
    }
}

3. 使用.net内置eventbus的简化实现

基于mediatr库的实现

// 安装mediatr nuget包
// install-package mediatr

// 定义事件/通知
public class stockcheckedevent : inotification
{
    public int productid { get; set; }
}

public class paymentprocessedevent : inotification
{
    public decimal amount { get; set; }
}

// 定义处理器
public class stockcheckedhandler : inotificationhandler<stockcheckedevent>
{
    private readonly imediator _mediator;
  
    public stockcheckedhandler(imediator mediator)
    {
        _mediator = mediator;
    }
  
    public async task handle(stockcheckedevent notification, cancellationtoken ct)
    {
        console.writeline($"stock checked for product {notification.productid}");
        await _mediator.publish(new paymentprocessedevent { amount = 99.99m }, ct);
    }
}

public class paymentprocessedhandler : inotificationhandler<paymentprocessedevent>
{
    public task handle(paymentprocessedevent notification, cancellationtoken ct)
    {
        console.writeline($"payment processed: {notification.amount}");
        console.writeline("order completed!");
        return task.completedtask;
    }
}

// 使用示例
var services = new servicecollection();
services.addmediatr(cfg => cfg.registerservicesfromassembly(assembly.getexecutingassembly()));
var provider = services.buildserviceprovider();

var mediator = provider.getrequiredservice<imediator>();
await mediator.publish(new stockcheckedevent { productid = 1 });

4. 比较与选择

实现方式优点缺点适用场景
经典中介者模式结构清晰,职责明确中介者类可能变得庞大复杂交互,需要集中控制
基于事件实现松耦合,易于扩展事件处理逻辑分散组件间交互简单,需要灵活扩展
action委托回调实现简单,轻量级不适合复杂交互简单流程,快速实现
mediatr事件总线专业解耦,支持异步需要引入第三方库企业级应用,需要强大事件处理

5. 最佳实践建议

  1. 简单场景:使用action委托或简单事件实现
  2. 中等复杂度:使用基于事件的协调器模式
  3. 企业级应用:考虑使用mediatr等事件总线库
  4. 保持一致性:项目中统一使用一种实现方式
  5. 适度抽象:不要过度设计,根据实际需求选择

八、在unity中的应用

示例1:ui系统管理

using unityengine;
using unityengine.ui;

// 中介者接口
public interface iuimediator
{
    void notify(uicomponent sender, string eventname);
}

// 具体中介者 - ui管理器
public class uimanager : monobehaviour, iuimediator
{
    public button startbutton;
    public button optionsbutton;
    public button quitbutton;
    public gameobject mainmenupanel;
    public gameobject optionspanel;
  
    private void start()
    {
        // 为每个ui组件设置中介者引用
        startbutton.getcomponent<uicomponent>().setmediator(this);
        optionsbutton.getcomponent<uicomponent>().setmediator(this);
        quitbutton.getcomponent<uicomponent>().setmediator(this);
  
        // 初始化ui状态
        mainmenupanel.setactive(true);
        optionspanel.setactive(false);
    }
  
    // 处理ui组件通知
    public void notify(uicomponent sender, string eventname)
    {
        switch (eventname)
        {
            case "startbuttonclicked":
                onstartgame();
                break;
            case "optionsbuttonclicked":
                onopenoptions();
                break;
            case "quitbuttonclicked":
                onquitgame();
                break;
            case "backbuttonclicked":
                onbacktomenu();
                break;
        }
    }
  
    private void onstartgame()
    {
        debug.log("开始游戏");
        mainmenupanel.setactive(false);
        // 这里可以添加游戏开始的逻辑
    }
  
    private void onopenoptions()
    {
        debug.log("打开选项菜单");
        mainmenupanel.setactive(false);
        optionspanel.setactive(true);
    }
  
    private void onquitgame()
    {
        debug.log("退出游戏");
        application.quit();
    }
  
    private void onbacktomenu()
    {
        debug.log("返回主菜单");
        optionspanel.setactive(false);
        mainmenupanel.setactive(true);
    }
}

// 同事类 - ui组件基类
public class uicomponent : monobehaviour
{
    protected iuimediator mediator;
  
    // 设置中介者
    public void setmediator(iuimediator mediator)
    {
        this.mediator = mediator;
    }
  
    // 通知中介者
    protected void notifymediator(string eventname)
    {
        mediator?.notify(this, eventname);
    }
}

// 具体同事类 - 开始按钮
public class startbutton : uicomponent
{
    private button button;
  
    private void awake()
    {
        button = getcomponent<button>();
        button.onclick.addlistener(onclick);
    }
  
    private void onclick()
    {
        notifymediator("startbuttonclicked");
    }
}

// 具体同事类 - 选项按钮
public class optionsbutton : uicomponent
{
    private button button;
  
    private void awake()
    {
        button = getcomponent<button>();
        button.onclick.addlistener(onclick);
    }
  
    private void onclick()
    {
        notifymediator("optionsbuttonclicked");
    }
}

// 具体同事类 - 退出按钮
public class quitbutton : uicomponent
{
    private button button;
  
    private void awake()
    {
        button = getcomponent<button>();
        button.onclick.addlistener(onclick);
    }
  
    private void onclick()
    {
        notifymediator("quitbuttonclicked");
    }
}

// 具体同事类 - 返回按钮
public class backbutton : uicomponent
{
    private button button;
  
    private void awake()
    {
        button = getcomponent<button>();
        button.onclick.addlistener(onclick);
    }
  
    private void onclick()
    {
        notifymediator("backbuttonclicked");
    }
}

示例2:游戏事件系统

using unityengine;
using system.collections.generic;

// 事件类型枚举
public enum gameeventtype
{
    playerdied,
    enemykilled,
    itemcollected,
    levelcompleted
}

// 中介者接口
public interface igameeventmediator
{
    void subscribe(gameeventtype eventtype, igameeventsubscriber subscriber);
    void unsubscribe(gameeventtype eventtype, igameeventsubscriber subscriber);
    void publish(gameeventtype eventtype, object sender, object eventdata);
}

// 具体中介者 - 游戏事件管理器
public class gameeventmanager : monobehaviour, igameeventmediator
{
    private dictionary<gameeventtype, list<igameeventsubscriber>> subscribers = 
        new dictionary<gameeventtype, list<igameeventsubscriber>>();
  
    // 订阅事件
    public void subscribe(gameeventtype eventtype, igameeventsubscriber subscriber)
    {
        if (!subscribers.containskey(eventtype))
        {
            subscribers[eventtype] = new list<igameeventsubscriber>();
        }
  
        if (!subscribers[eventtype].contains(subscriber))
        {
            subscribers[eventtype].add(subscriber);
        }
    }
  
    // 取消订阅
    public void unsubscribe(gameeventtype eventtype, igameeventsubscriber subscriber)
    {
        if (subscribers.containskey(eventtype))
        {
            subscribers[eventtype].remove(subscriber);
        }
    }
  
    // 发布事件
    public void publish(gameeventtype eventtype, object sender, object eventdata)
    {
        if (subscribers.containskey(eventtype))
        {
            foreach (var subscriber in subscribers[eventtype])
            {
                subscriber.onevent(eventtype, sender, eventdata);
            }
        }
    }
}

// 同事接口 - 事件订阅者
public interface igameeventsubscriber
{
    void onevent(gameeventtype eventtype, object sender, object eventdata);
}

// 具体同事类 - 玩家控制器
public class playercontroller : monobehaviour, igameeventsubscriber
{
    private igameeventmediator eventmediator;
    public int health = 100;
  
    private void start()
    {
        eventmediator = findobjectoftype<gameeventmanager>();
        eventmediator.subscribe(gameeventtype.playerdied, this);
    }
  
    private void ondestroy()
    {
        eventmediator?.unsubscribe(gameeventtype.playerdied, this);
    }
  
    public void takedamage(int damage)
    {
        health -= damage;
  
        if (health <= 0)
        {
            eventmediator.publish(gameeventtype.playerdied, this, null);
        }
    }
  
    public void onevent(gameeventtype eventtype, object sender, object eventdata)
    {
        if (eventtype == gameeventtype.playerdied && sender == this)
        {
            debug.log("玩家死亡事件处理");
            // 处理玩家死亡逻辑
        }
    }
}

// 具体同事类 - 成就系统
public class achievementsystem : monobehaviour, igameeventsubscriber
{
    private igameeventmediator eventmediator;
  
    private void start()
    {
        eventmediator = findobjectoftype<gameeventmanager>();
        eventmediator.subscribe(gameeventtype.enemykilled, this);
        eventmediator.subscribe(gameeventtype.itemcollected, this);
    }
  
    private void ondestroy()
    {
        eventmediator?.unsubscribe(gameeventtype.enemykilled, this);
        eventmediator?.unsubscribe(gameeventtype.itemcollected, this);
    }
  
    public void onevent(gameeventtype eventtype, object sender, object eventdata)
    {
        switch (eventtype)
        {
            case gameeventtype.enemykilled:
                debug.log("成就系统: 敌人被击杀");
                // 更新击杀成就
                break;
            case gameeventtype.itemcollected:
                debug.log("成就系统: 物品被收集");
                // 更新收集成就
                break;
        }
    }
}

// 具体同事类 - 音频管理器
public class audiomanager : monobehaviour, igameeventsubscriber
{
    private igameeventmediator eventmediator;
  
    private void start()
    {
        eventmediator = findobjectoftype<gameeventmanager>();
        eventmediator.subscribe(gameeventtype.playerdied, this);
        eventmediator.subscribe(gameeventtype.levelcompleted, this);
    }
  
    private void ondestroy()
    {
        eventmediator?.unsubscribe(gameeventtype.playerdied, this);
        eventmediator?.unsubscribe(gameeventtype.levelcompleted, this);
    }
  
    public void onevent(gameeventtype eventtype, object sender, object eventdata)
    {
        switch (eventtype)
        {
            case gameeventtype.playerdied:
                debug.log("播放死亡音效");
                // 播放死亡音效
                break;
            case gameeventtype.levelcompleted:
                debug.log("播放关卡完成音效");
                // 播放胜利音效
                break;
        }
    }
}

示例3:ai协调系统

using unityengine;
using system.collections.generic;

// 中介者接口
public interface iaimediator
{
    void registerai(aientity ai);
    void unregisterai(aientity ai);
    void sendmessage(aientity sender, string message);
}

// 具体中介者 - ai协调器
public class aicoordinator : monobehaviour, iaimediator
{
    private list<aientity> aientities = new list<aientity>();
  
    // 注册ai实体
    public void registerai(aientity ai)
    {
        if (!aientities.contains(ai))
        {
            aientities.add(ai);
        }
    }
  
    // 注销ai实体
    public void unregisterai(aientity ai)
    {
        aientities.remove(ai);
    }
  
    // 广播消息
    public void sendmessage(aientity sender, string message)
    {
        foreach (var ai in aientities)
        {
            if (ai != sender) // 不发送给自己
            {
                ai.receivemessage(message);
            }
        }
    }
}

// 同事类 - ai实体基类
public abstract class aientity : monobehaviour
{
    protected iaimediator mediator;
  
    // 设置中介者
    public void setmediator(iaimediator mediator)
    {
        this.mediator = mediator;
        mediator.registerai(this);
    }
  
    // 发送消息
    protected void sendtoothers(string message)
    {
        mediator?.sendmessage(this, message);
    }
  
    // 接收消息
    public abstract void receivemessage(string message);
  
    private void ondestroy()
    {
        mediator?.unregisterai(this);
    }
}

// 具体同事类 - 守卫ai
public class guardai : aientity
{
    private bool isalerted = false;
  
    private void start()
    {
        // 在中介者中注册
        setmediator(findobjectoftype<aicoordinator>());
    }
  
    // 发现玩家
    public void spotplayer()
    {
        debug.log("守卫发现玩家!");
        isalerted = true;
        sendtoothers("playerspotted");
    }
  
    // 接收消息
    public override void receivemessage(string message)
    {
        if (message == "playerspotted" && !isalerted)
        {
            debug.log("守卫收到警报: 玩家被发现!");
            isalerted = true;
            // 进入警戒状态
        }
    }
}

// 具体同事类 - 巡逻ai
public class patrolai : aientity
{
    private bool isalerted = false;
  
    private void start()
    {
        // 在中介者中注册
        setmediator(findobjectoftype<aicoordinator>());
    }
  
    // 发现玩家
    public void spotplayer()
    {
        debug.log("巡逻ai发现玩家!");
        isalerted = true;
        sendtoothers("playerspotted");
    }
  
    // 接收消息
    public override void receivemessage(string message)
    {
        if (message == "playerspotted" && !isalerted)
        {
            debug.log("巡逻ai收到警报: 玩家被发现!");
            isalerted = true;
            // 改变巡逻路线
        }
    }
}

// 具体同事类 - 狙击手ai
public class sniperai : aientity
{
    private bool isalerted = false;
  
    private void start()
    {
        // 在中介者中注册
        setmediator(findobjectoftype<aicoordinator>());
    }
  
    // 接收消息
    public override void receivemessage(string message)
    {
        if (message == "playerspotted" && !isalerted)
        {
            debug.log("狙击手收到警报: 玩家被发现!准备狙击...");
            isalerted = true;
            // 进入狙击位置
        }
    }
}

在unity中的实现建议

  1. 使用scriptableobject:可以将中介者实现为scriptableobject,便于在编辑器中配置
  2. 与事件系统结合:unity自身的eventsystem也可以看作是一种中介者模式的实现
  3. 考虑性能:对于高频交互,注意中介者可能成为性能瓶颈
  4. 避免过度使用:不是所有对象交互都需要中介者,简单交互可以直接通信
  5. 分层设计:可以为不同子系统设计不同的中介者,避免单个中介者过于复杂

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com