欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時(shí)間:2025年08月14日 08:53:44   作者:_克克克  
中介者模式通過(guò)中介者封裝對(duì)象交互,降低耦合度,集中控制邏輯,適用于復(fù)雜系統(tǒng)組件交互場(chǎng)景,C#中可用事件、委托或MediatR實(shí)現(xiàn),提升可維護(hù)性與靈活性

C#中的中介者模式詳解

中介者模式(Mediator Pattern)是一種行為設(shè)計(jì)模式,它能減少對(duì)象之間混亂無(wú)序的依賴關(guān)系,通過(guò)引入一個(gè)中介者對(duì)象來(lái)封裝一系列對(duì)象之間的交互。

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

1. 定義

中介者模式定義了一個(gè)對(duì)象來(lái)封裝一組對(duì)象之間的交互方式,使各對(duì)象不需要顯式地相互引用,從而使其耦合松散,而且可以獨(dú)立地改變它們之間的交互。

2. 組成要素

  • Mediator(中介者接口) :定義各個(gè)同事對(duì)象通信的接口
  • ConcreteMediator(具體中介者) :實(shí)現(xiàn)中介者接口,協(xié)調(diào)各同事對(duì)象的交互
  • Colleague(同事類) :每個(gè)同事對(duì)象都知道它的中介者對(duì)象,與其他同事通信時(shí)都通過(guò)中介者

3. 模式結(jié)構(gòu)

[同事A] ────> [中介者] <─── [同事B]
    ↑____________|____________↑

二、中介者模式的特點(diǎn)

1. 優(yōu)點(diǎn)

  • 降低耦合度:將對(duì)象之間的網(wǎng)狀結(jié)構(gòu)變?yōu)樾切徒Y(jié)構(gòu)
  • 集中控制:將交互復(fù)雜性集中到中介者中
  • 簡(jiǎn)化對(duì)象協(xié)議:用一對(duì)多的交互代替多對(duì)多的交互
  • 易于擴(kuò)展:新增同事類只需修改中介者或新增具體中介者

2. 缺點(diǎn)

  • 中介者可能變得復(fù)雜:如果同事類過(guò)多,中介者會(huì)變得龐大復(fù)雜
  • 過(guò)度集中化:中介者集中了太多控制邏輯,可能成為"上帝對(duì)象"

三、中介者模式的實(shí)現(xiàn)方式

1. 基本實(shí)現(xiàn)

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

// 基礎(chǔ)同事類
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. 更復(fù)雜的實(shí)現(xiàn)(聊天室示例)

// 中介者接口
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!");

四、中介者模式的使用場(chǎng)景

1. 典型使用場(chǎng)景

  1. 對(duì)象間存在復(fù)雜的引用關(guān)系:當(dāng)系統(tǒng)中對(duì)象之間存在復(fù)雜的網(wǎng)狀引用關(guān)系,導(dǎo)致系統(tǒng)結(jié)構(gòu)混亂且難以理解時(shí)。
  2. 需要集中控制對(duì)象間的交互:當(dāng)多個(gè)類之間有復(fù)雜的交互邏輯,且這些邏輯需要集中管理時(shí)。
  3. 想定制分布在多個(gè)類中的行為:當(dāng)行為分布在多個(gè)類中,但又需要根據(jù)需求改變這些行為時(shí)。
  4. GUI組件交互:圖形用戶界面中,各種控件(按鈕、文本框等)之間的交互。
  5. 消息傳遞系統(tǒng):如聊天應(yīng)用、通知系統(tǒng)等需要多方通信的場(chǎng)景。

2. 實(shí)際應(yīng)用示例

示例1:航空管制系統(tǒng)

// 航空交通管制中介者接口
public interface IAirTrafficControl
{
    // 注冊(cè)飛機(jī)到管制系統(tǒng)
    void RegisterAircraft(Aircraft aircraft);
  
    // 發(fā)送警告消息(發(fā)送者飛機(jī) + 消息內(nèi)容)
    void SendWarningMessage(Aircraft sender, string message);
}

// 飛機(jī)類(同事類)
public class Aircraft
{
    // 飛機(jī)呼號(hào)(唯一標(biāo)識(shí))
    public string CallSign { get; }
  
    // 持有對(duì)航空管制中心(中介者)的引用
    private IAirTrafficControl _atc;
  
    // 構(gòu)造函數(shù):初始化飛機(jī)并注冊(cè)到管制系統(tǒng)
    public Aircraft(string callSign, IAirTrafficControl atc)
    {
        CallSign = callSign;
        _atc = atc;
        _atc.RegisterAircraft(this); // 自動(dòng)注冊(cè)到管制系統(tǒng)
    }
  
    // 發(fā)送警告消息(通過(guò)管制中心轉(zhuǎn)發(fā))
    public void SendWarning(string message)
    {
        // 不直接聯(lián)系其他飛機(jī),而是通過(guò)管制中心發(fā)送
        _atc.SendWarningMessage(this, message);
    }
  
    // 接收來(lái)自其他飛機(jī)的警告
    public void ReceiveWarning(string from, string message)
    {
        // 打印接收到的警告信息
        Console.WriteLine($"{CallSign} received from {from}: {message}");
    }
}

// 塔臺(tái)管制中心(具體中介者實(shí)現(xiàn))
public class Tower : IAirTrafficControl
{
    // 保存所有注冊(cè)的飛機(jī)列表
    private List<Aircraft> _aircrafts = new List<Aircraft>();
  
    // 注冊(cè)飛機(jī)到管制系統(tǒng)
    public void RegisterAircraft(Aircraft aircraft)
    {
        // 防止重復(fù)注冊(cè)
        if (!_aircrafts.Contains(aircraft))
        {
            _aircrafts.Add(aircraft);
        }
    }
  
    // 處理警告消息轉(zhuǎn)發(fā)
    public void SendWarningMessage(Aircraft sender, string message)
    {
        // 遍歷所有已注冊(cè)的飛機(jī)(排除發(fā)送者自己)
        foreach (var aircraft in _aircrafts.Where(a => a != sender))
        {
            // 將消息轉(zhuǎn)發(fā)給其他飛機(jī)
            aircraft.ReceiveWarning(sender.CallSign, message);
        }
    }
}

示例2:訂單處理系統(tǒng)

// 訂單中介者接口
public interface IOrderMediator
{
    // 通知方法:組件通過(guò)此方法與中介者通信
    // sender - 觸發(fā)事件的組件
    // eventType - 事件類型標(biāo)識(shí)
    void Notify(OrderComponent sender, string eventType);
}

// 訂單組件基類(抽象同事類)
public abstract class OrderComponent
{
    // 持有對(duì)中介者的引用
    protected IOrderMediator _mediator;
  
    // 構(gòu)造函數(shù):注入中介者實(shí)例
    public OrderComponent(IOrderMediator mediator)
    {
        _mediator = mediator;
    }
}

// 庫(kù)存系統(tǒng)(具體同事類)
public class InventorySystem : OrderComponent
{
    // 構(gòu)造函數(shù):調(diào)用基類構(gòu)造函數(shù)
    public InventorySystem(IOrderMediator mediator) : base(mediator) { }
  
    // 檢查庫(kù)存方法
    public void CheckStock()
    {
        Console.WriteLine("Checking stock...");
        // 通知中介者庫(kù)存已檢查
        _mediator.Notify(this, "StockChecked");
    }
  
    // 更新庫(kù)存方法
    public void UpdateStock()
    {
        Console.WriteLine("Updating stock...");
    }
}

// 支付系統(tǒng)(具體同事類)
public class PaymentSystem : OrderComponent
{
    // 構(gòu)造函數(shù):調(diào)用基類構(gòu)造函數(shù)
    public PaymentSystem(IOrderMediator mediator) : base(mediator) { }
  
    // 處理支付方法
    public void ProcessPayment()
    {
        Console.WriteLine("Processing payment...");
        // 通知中介者支付已處理
        _mediator.Notify(this, "PaymentProcessed");
    }
}

// 訂單中介者實(shí)現(xiàn)(具體中介者)
public class OrderMediator : IOrderMediator
{
    // 持有庫(kù)存系統(tǒng)引用
    private InventorySystem _inventory;
    // 持有支付系統(tǒng)引用
    private PaymentSystem _payment;
  
    // 構(gòu)造函數(shù):注入需要的組件
    public OrderMediator(InventorySystem inventory, PaymentSystem payment)
    {
        _inventory = inventory;
        _payment = payment;
    }
  
    // 實(shí)現(xiàn)通知處理方法
    public void Notify(OrderComponent sender, string eventType)
    {
        // 如果是庫(kù)存系統(tǒng)且事件類型為"StockChecked"
        if (sender is InventorySystem && eventType == "StockChecked")
        {
            // 觸發(fā)支付系統(tǒng)處理支付
            _payment.ProcessPayment();
        }
        // 如果是支付系統(tǒng)且事件類型為"PaymentProcessed"
        else if (sender is PaymentSystem && eventType == "PaymentProcessed")
        {
            // 更新庫(kù)存
            _inventory.UpdateStock();
            Console.WriteLine("Order completed!");
        }
    }
}

五、中介者模式與其他模式的關(guān)系

與外觀模式的區(qū)別

  • 外觀模式為子系統(tǒng)提供簡(jiǎn)化接口,但不添加新功能
  • 中介者模式集中同事對(duì)象間的通信,可以添加協(xié)調(diào)邏輯

與觀察者模式的區(qū)別

  • 觀察者模式通過(guò)訂閱/發(fā)布機(jī)制實(shí)現(xiàn)單向通信
  • 中介者模式對(duì)象間通過(guò)中介者進(jìn)行雙向通信

與命令模式結(jié)合

  • 可以使用命令模式將請(qǐng)求封裝為對(duì)象,由中介者管理這些命令

六、最佳實(shí)踐

合理劃分責(zé)任

  • 中介者應(yīng)只負(fù)責(zé)協(xié)調(diào),不承擔(dān)業(yè)務(wù)邏輯
  • 避免創(chuàng)建"上帝對(duì)象"

考慮使用事件

  • 在C#中可以使用事件機(jī)制實(shí)現(xiàn)輕量級(jí)中介者

適度使用

  • 只在對(duì)象間交互確實(shí)復(fù)雜時(shí)使用
  • 簡(jiǎn)單交互直接引用可能更合適

可測(cè)試性設(shè)計(jì)

  • 使中介者易于替換,方便單元測(cè)試

性能考慮

  • 高頻交互場(chǎng)景需評(píng)估中介者帶來(lái)的性能影響

七、總結(jié)

中介者模式是管理復(fù)雜對(duì)象交互的強(qiáng)大工具,特別適用于以下場(chǎng)景:

  • 對(duì)象間存在大量直接連接
  • 系統(tǒng)組件難以復(fù)用
  • 交互邏輯分散難以理解
  • 需要集中控制對(duì)象間通信

在C#中實(shí)現(xiàn)中介者模式時(shí),可以:

  1. 定義清晰的中介者接口
  2. 使同事類只依賴于中介者
  3. 將復(fù)雜的交互邏輯封裝在中介者中
  4. 考慮使用事件或委托簡(jiǎn)化實(shí)現(xiàn)

正確使用中介者模式可以顯著降低系統(tǒng)復(fù)雜度,提高代碼的可維護(hù)性和靈活性。

八、使用事件或委托簡(jiǎn)化實(shí)現(xiàn)中介者模式

中介者模式可以通過(guò)C#的事件和委托機(jī)制來(lái)簡(jiǎn)化實(shí)現(xiàn),這種方式可以減少中介者類的復(fù)雜性,同時(shí)保持對(duì)象間的解耦。下面我將展示如何使用事件來(lái)重構(gòu)中介者模式。

1. 基于事件的簡(jiǎn)化實(shí)現(xiàn)

基本架構(gòu)

// 定義事件參數(shù)基類
public abstract class OrderEventArgs : EventArgs
{
    public string EventType { get; set; }
}

// 庫(kù)存系統(tǒng)事件參數(shù)
public class InventoryEventArgs : OrderEventArgs
{
    public int ProductId { get; set; }
    public int Quantity { get; set; }
}

// 支付系統(tǒng)事件參數(shù)
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;
  
    // 觸發(fā)事件的方法
    protected void RaiseEvent(OrderEventArgs e)
    {
        OnOrderEvent?.Invoke(this, e);
    }
}

// 庫(kù)存系統(tǒng)實(shí)現(xiàn)
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 // 假設(shè)檢查到有100個(gè)庫(kù)存
        });
    }
  
    public void UpdateStock(int productId, int quantity)
    {
        Console.WriteLine($"Updating stock for product {productId}, quantity: {quantity}");
    }
}

// 支付系統(tǒng)實(shí)現(xiàn)
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
        });
    }
}

事件協(xié)調(diào)器(輕量級(jí)中介者)

public class OrderEventCoordinator
{
    private readonly InventorySystem _inventory;
    private readonly PaymentSystem _payment;
  
    public OrderEventCoordinator(InventorySystem inventory, PaymentSystem payment)
    {
        _inventory = inventory;
        _payment = payment;
  
        // 訂閱庫(kù)存系統(tǒng)事件
        _inventory.OnOrderEvent += HandleInventoryEvent;
  
        // 訂閱支付系統(tǒng)事件
        _payment.OnOrderEvent += HandlePaymentEvent;
    }
  
    private void HandleInventoryEvent(object sender, OrderEventArgs e)
    {
        if (e is InventoryEventArgs args && args.EventType == "StockChecked")
        {
            // 庫(kù)存檢查完成后處理支付
            _payment.ProcessPayment(99.99m, "CreditCard");
        }
    }
  
    private void HandlePaymentEvent(object sender, OrderEventArgs e)
    {
        if (e is PaymentEventArgs args && args.EventType == "PaymentProcessed")
        {
            // 支付完成后更新庫(kù)存
            _inventory.UpdateStock(1, -1); // 假設(shè)產(chǎn)品ID為1,減少1個(gè)庫(kù)存
            Console.WriteLine("Order completed!");
        }
    }
}

2. 使用Action委托的簡(jiǎn)化實(shí)現(xiàn)

更輕量的實(shí)現(xiàn)方式

// 組件基類(使用Action委托)
public abstract class OrderComponent
{
    protected Action<string, object> MediatorCallback { get; }
  
    public OrderComponent(Action<string, object> mediatorCallback)
    {
        MediatorCallback = mediatorCallback;
    }
}

// 庫(kù)存系統(tǒng)
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}");
    }
}

// 支付系統(tǒng)
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表達(dá)式作為中介者
public class Program
{
    public static void Main()
    {
        // 創(chuàng)建支付系統(tǒng)并定義其回調(diào)
        var payment = new PaymentSystem((eventType, data) => 
        {
            if (eventType == "PaymentProcessed")
            {
                Console.WriteLine("Payment processed callback");
            }
        });
  
        // 創(chuàng)建庫(kù)存系統(tǒng)并定義完整流程
        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!");
            }
        });
  
        // 啟動(dòng)流程
        inventory.CheckStock(1);
    }
}

3. 使用.NET內(nèi)置EventBus的簡(jiǎn)化實(shí)現(xiàn)

基于MediatR庫(kù)的實(shí)現(xiàn)

// 安裝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. 比較與選擇

實(shí)現(xiàn)方式優(yōu)點(diǎn)缺點(diǎn)適用場(chǎng)景
經(jīng)典中介者模式結(jié)構(gòu)清晰,職責(zé)明確中介者類可能變得龐大復(fù)雜交互,需要集中控制
基于事件實(shí)現(xiàn)松耦合,易于擴(kuò)展事件處理邏輯分散組件間交互簡(jiǎn)單,需要靈活擴(kuò)展
Action委托回調(diào)實(shí)現(xiàn)簡(jiǎn)單,輕量級(jí)不適合復(fù)雜交互簡(jiǎn)單流程,快速實(shí)現(xiàn)
MediatR事件總線專業(yè)解耦,支持異步需要引入第三方庫(kù)企業(yè)級(jí)應(yīng)用,需要強(qiáng)大事件處理

5. 最佳實(shí)踐建議

  1. 簡(jiǎn)單場(chǎng)景:使用Action委托或簡(jiǎn)單事件實(shí)現(xiàn)
  2. 中等復(fù)雜度:使用基于事件的協(xié)調(diào)器模式
  3. 企業(yè)級(jí)應(yīng)用:考慮使用MediatR等事件總線庫(kù)
  4. 保持一致性:項(xiàng)目中統(tǒng)一使用一種實(shí)現(xiàn)方式
  5. 適度抽象:不要過(guò)度設(shè)計(jì),根據(jù)實(shí)際需求選擇

八、在Unity中的應(yīng)用

示例1:UI系統(tǒng)管理

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()
    {
        // 為每個(gè)UI組件設(shè)置中介者引用
        startButton.GetComponent<UIComponent>().SetMediator(this);
        optionsButton.GetComponent<UIComponent>().SetMediator(this);
        quitButton.GetComponent<UIComponent>().SetMediator(this);
  
        // 初始化UI狀態(tài)
        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("開(kāi)始游戲");
        mainMenuPanel.SetActive(false);
        // 這里可以添加游戲開(kāi)始的邏輯
    }
  
    private void OnOpenOptions()
    {
        Debug.Log("打開(kāi)選項(xiàng)菜單");
        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;
  
    // 設(shè)置中介者
    public void SetMediator(IUIMediator mediator)
    {
        this.mediator = mediator;
    }
  
    // 通知中介者
    protected void NotifyMediator(string eventName)
    {
        mediator?.Notify(this, eventName);
    }
}

// 具體同事類 - 開(kāi)始按鈕
public class StartButton : UIComponent
{
    private Button button;
  
    private void Awake()
    {
        button = GetComponent<Button>();
        button.onClick.AddListener(OnClick);
    }
  
    private void OnClick()
    {
        NotifyMediator("StartButtonClicked");
    }
}

// 具體同事類 - 選項(xiàng)按鈕
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:游戲事件系統(tǒng)

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);
        }
    }
  
    // 發(fā)布事件
    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("玩家死亡事件處理");
            // 處理玩家死亡邏輯
        }
    }
}

// 具體同事類 - 成就系統(tǒng)
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("成就系統(tǒng): 敵人被擊殺");
                // 更新?lián)魵⒊删?
                break;
            case GameEventType.ItemCollected:
                Debug.Log("成就系統(tǒng): 物品被收集");
                // 更新收集成就
                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("播放關(guān)卡完成音效");
                // 播放勝利音效
                break;
        }
    }
}

示例3:AI協(xié)調(diào)系統(tǒng)

using UnityEngine;
using System.Collections.Generic;

// 中介者接口
public interface IAIMediator
{
    void RegisterAI(AIEntity ai);
    void UnregisterAI(AIEntity ai);
    void SendMessage(AIEntity sender, string message);
}

// 具體中介者 - AI協(xié)調(diào)器
public class AICoordinator : MonoBehaviour, IAIMediator
{
    private List<AIEntity> aiEntities = new List<AIEntity>();
  
    // 注冊(cè)AI實(shí)體
    public void RegisterAI(AIEntity ai)
    {
        if (!aiEntities.Contains(ai))
        {
            aiEntities.Add(ai);
        }
    }
  
    // 注銷AI實(shí)體
    public void UnregisterAI(AIEntity ai)
    {
        aiEntities.Remove(ai);
    }
  
    // 廣播消息
    public void SendMessage(AIEntity sender, string message)
    {
        foreach (var ai in aiEntities)
        {
            if (ai != sender) // 不發(fā)送給自己
            {
                ai.ReceiveMessage(message);
            }
        }
    }
}

// 同事類 - AI實(shí)體基類
public abstract class AIEntity : MonoBehaviour
{
    protected IAIMediator mediator;
  
    // 設(shè)置中介者
    public void SetMediator(IAIMediator mediator)
    {
        this.mediator = mediator;
        mediator.RegisterAI(this);
    }
  
    // 發(fā)送消息
    protected void SendToOthers(string message)
    {
        mediator?.SendMessage(this, message);
    }
  
    // 接收消息
    public abstract void ReceiveMessage(string message);
  
    private void OnDestroy()
    {
        mediator?.UnregisterAI(this);
    }
}

// 具體同事類 - 守衛(wèi)AI
public class GuardAI : AIEntity
{
    private bool isAlerted = false;
  
    private void Start()
    {
        // 在中介者中注冊(cè)
        SetMediator(FindObjectOfType<AICoordinator>());
    }
  
    // 發(fā)現(xiàn)玩家
    public void SpotPlayer()
    {
        Debug.Log("守衛(wèi)發(fā)現(xiàn)玩家!");
        isAlerted = true;
        SendToOthers("PlayerSpotted");
    }
  
    // 接收消息
    public override void ReceiveMessage(string message)
    {
        if (message == "PlayerSpotted" && !isAlerted)
        {
            Debug.Log("守衛(wèi)收到警報(bào): 玩家被發(fā)現(xiàn)!");
            isAlerted = true;
            // 進(jìn)入警戒狀態(tài)
        }
    }
}

// 具體同事類 - 巡邏AI
public class PatrolAI : AIEntity
{
    private bool isAlerted = false;
  
    private void Start()
    {
        // 在中介者中注冊(cè)
        SetMediator(FindObjectOfType<AICoordinator>());
    }
  
    // 發(fā)現(xiàn)玩家
    public void SpotPlayer()
    {
        Debug.Log("巡邏AI發(fā)現(xiàn)玩家!");
        isAlerted = true;
        SendToOthers("PlayerSpotted");
    }
  
    // 接收消息
    public override void ReceiveMessage(string message)
    {
        if (message == "PlayerSpotted" && !isAlerted)
        {
            Debug.Log("巡邏AI收到警報(bào): 玩家被發(fā)現(xiàn)!");
            isAlerted = true;
            // 改變巡邏路線
        }
    }
}

// 具體同事類 - 狙擊手AI
public class SniperAI : AIEntity
{
    private bool isAlerted = false;
  
    private void Start()
    {
        // 在中介者中注冊(cè)
        SetMediator(FindObjectOfType<AICoordinator>());
    }
  
    // 接收消息
    public override void ReceiveMessage(string message)
    {
        if (message == "PlayerSpotted" && !isAlerted)
        {
            Debug.Log("狙擊手收到警報(bào): 玩家被發(fā)現(xiàn)!準(zhǔn)備狙擊...");
            isAlerted = true;
            // 進(jìn)入狙擊位置
        }
    }
}

在Unity中的實(shí)現(xiàn)建議

  1. 使用ScriptableObject:可以將中介者實(shí)現(xiàn)為ScriptableObject,便于在編輯器中配置
  2. 與事件系統(tǒng)結(jié)合:Unity自身的EventSystem也可以看作是一種中介者模式的實(shí)現(xiàn)
  3. 考慮性能:對(duì)于高頻交互,注意中介者可能成為性能瓶頸
  4. 避免過(guò)度使用:不是所有對(duì)象交互都需要中介者,簡(jiǎn)單交互可以直接通信
  5. 分層設(shè)計(jì):可以為不同子系統(tǒng)設(shè)計(jì)不同的中介者,避免單個(gè)中介者過(guò)于復(fù)雜

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 在C#中發(fā)送自定義HTML格式郵件的示例詳解

    在C#中發(fā)送自定義HTML格式郵件的示例詳解

    在C#中發(fā)送自定義HTML格式郵件是一項(xiàng)常見(jiàn)的任務(wù),這在開(kāi)發(fā)電子郵件營(yíng)銷系統(tǒng)或任何需要通過(guò)電子郵件與用戶溝通的應(yīng)用程序中都非常重要,以下是如何在C#中發(fā)送自定義HTML格式郵件的詳解與示例,需要的朋友可以參考下
    2024-07-07
  • c#中Empty()和DefalutIfEmpty()用法分析

    c#中Empty()和DefalutIfEmpty()用法分析

    這篇文章主要介紹了c#中Empty()和DefalutIfEmpty()用法,以實(shí)例形式分析了針對(duì)不同情況下Empty()和DefalutIfEmpty()用法區(qū)別,需要的朋友可以參考下
    2014-11-11
  • unity實(shí)現(xiàn)車方向盤轉(zhuǎn)動(dòng)效果

    unity實(shí)現(xiàn)車方向盤轉(zhuǎn)動(dòng)效果

    這篇文章主要為大家詳細(xì)介紹了unity實(shí)現(xiàn)車方向盤轉(zhuǎn)動(dòng)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • Unity shader實(shí)現(xiàn)移動(dòng)端模擬深度水效果

    Unity shader實(shí)現(xiàn)移動(dòng)端模擬深度水效果

    這篇文章主要為大家詳細(xì)介紹了Unity shader實(shí)現(xiàn)移動(dòng)端模擬深度水效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • C# WinForm控件對(duì)透明圖片重疊時(shí)出現(xiàn)圖片不透明的簡(jiǎn)單解決方法

    C# WinForm控件對(duì)透明圖片重疊時(shí)出現(xiàn)圖片不透明的簡(jiǎn)單解決方法

    這篇文章主要介紹了C# WinForm控件對(duì)透明圖片重疊時(shí)出現(xiàn)圖片不透明的簡(jiǎn)單解決方法,結(jié)合實(shí)例形式分析了WinForm圖片重疊后造成圖片不透明的原因與相應(yīng)的解決方法,需要的朋友可以參考下
    2016-06-06
  • C#實(shí)現(xiàn)簡(jiǎn)單的飛行棋游戲

    C#實(shí)現(xiàn)簡(jiǎn)單的飛行棋游戲

    這篇文章主要為大家詳細(xì)介紹了C#實(shí)現(xiàn)簡(jiǎn)單的飛行棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • C#設(shè)計(jì)模式之ChainOfResponsibility職責(zé)鏈模式解決真假美猴王問(wèn)題實(shí)例

    C#設(shè)計(jì)模式之ChainOfResponsibility職責(zé)鏈模式解決真假美猴王問(wèn)題實(shí)例

    這篇文章主要介紹了C#設(shè)計(jì)模式之ChainOfResponsibility職責(zé)鏈模式解決真假美猴王問(wèn)題,簡(jiǎn)單說(shuō)明了責(zé)任鏈模式的概念,并結(jié)合《西游記》中真假美猴王故事背景為實(shí)例分析了責(zé)任鏈模式的具體使用技巧,需要的朋友可以參考下
    2017-09-09
  • 如何搭建新的WPF項(xiàng)目框架

    如何搭建新的WPF項(xiàng)目框架

    這篇文章主要介紹了如何搭建新的WPF項(xiàng)目框架,在項(xiàng)目開(kāi)發(fā)中比較常見(jiàn)的開(kāi)發(fā)模式就是MVVM模式,使用MVVM框架開(kāi)發(fā)好處:1、框架較輕,2、學(xué)習(xí)成本低、3、適用大多數(shù)中小型項(xiàng)目,4、相對(duì)于微軟的prism框架更容易上手,需要的朋友可以參考下
    2015-07-07
  • C#網(wǎng)絡(luò)適配器簡(jiǎn)單操作

    C#網(wǎng)絡(luò)適配器簡(jiǎn)單操作

    這篇文章主要介紹了C#網(wǎng)絡(luò)適配器簡(jiǎn)單操作,提供多種相關(guān)的輔助方法類,感興趣的小伙伴們可以參考一下
    2016-10-10
  • C#使用dir命令實(shí)現(xiàn)文件搜索功能示例

    C#使用dir命令實(shí)現(xiàn)文件搜索功能示例

    這篇文章主要介紹了C#使用dir命令實(shí)現(xiàn)文件搜索功能,結(jié)合具體實(shí)例形式分析了C#調(diào)用與使用cmd命令相關(guān)操作技巧,需要的朋友可以參考下
    2017-07-07

最新評(píng)論