小言_互联网的博客

用Unity写设计模式-中介者模式

249人阅读  评论(0)

中介者模式介绍

用一个中介对象封装一系列的对象交互,

  • 中介者使各对象不需要显示地相互作用,从而使其耦合松散

  • 而且可以独立地改变它们之间的交互。

  • Mediator 中介(IChatroom)

定义了一个与同事对象通信的接口

  • ConcreteMediator 具体中介类(聊天室)

通过协调同事对象来实现协作行为
认识并维护同事

  • Colleague classes 同事类(参与者)

每个同事类都知道它的Mediator对象
每个同事在本应与另一个同事沟通的时候,都会与调解人进行沟通

中介者模式

using UnityEngine;
using System.Collections;

public class MediatorStructure : MonoBehaviour
{
   
    void Start()
    {
   
        ConcreteMediator m = new ConcreteMediator();

        ConcreteColleague1 c1 = new ConcreteColleague1(m);
        ConcreteColleague2 c2 = new ConcreteColleague2(m);

        m.Colleague1 = c1;
        m.Colleague2 = c2;

        c1.Send("How are you?");
        c2.Send("Fine, thanks");

    }
}

/// <summary>
/// The 'Mediator' abstract class
/// </summary>
abstract class Mediator
{
   
    public abstract void Send(string message,Colleague colleague);
}

/// <summary>
/// The 'ConcreteMediator' class
/// </summary>
class ConcreteMediator : Mediator
{
   
    private ConcreteColleague1 _colleague1;
    private ConcreteColleague2 _colleague2;

    public ConcreteColleague1 Colleague1
    {
   
        set {
    _colleague1 = value; }
    }

    public ConcreteColleague2 Colleague2
    {
   
        set {
    _colleague2 = value; }
    }

    public override void Send(string message,Colleague colleague)
    {
   
        if (colleague == _colleague1)
        {
   
            _colleague2.Notify(message);
        }
        else
        {
   
            _colleague1.Notify(message);
        }
    }
}

/// <summary>
/// The 'Colleague' abstract class
/// </summary>
abstract class Colleague
{
   
    protected Mediator mediator;

    // Constructor
    public Colleague(Mediator mediator)
    {
   
        this.mediator = mediator;
    }
}

/// <summary>
/// A 'ConcreteColleague' class
/// </summary>
class ConcreteColleague1 : Colleague
{
   
    // Constructor
    public ConcreteColleague1(Mediator mediator)
        : base(mediator)
    {
   
    }

    public void Send(string message)
    {
   
        mediator.Send(message, this);
    }

    public void Notify(string message)
    {
   
        Debug.Log("Colleague1 gets message: "+ message);
    }
}

/// <summary>
/// A 'ConcreteColleague' class
/// </summary>
class ConcreteColleague2 : Colleague
{
   
    // Constructor
    public ConcreteColleague2(Mediator mediator)
        : base(mediator)
    {
   
    }

    public void Send(string message)
    {
   
        mediator.Send(message, this);
    }

    public void Notify(string message)
    {
   
        Debug.Log("Colleague2 gets message: "+ message);
    }
}

中介者模式案例1

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

//这段真实的代码演示了促进之间松散耦合通信的中介模式  
//注册聊天室的不同参与者。 聊天室是所有交流发生的中心枢纽。  
//此时,聊天室中只实现了一对一的通信,但如果改为一对多就很简单了。  

namespace MediatorExample1
{
   
    public class MediatorExample1 : MonoBehaviour
    {
   
        void Start()
        {
   
            // Create chatroom
            Chatroom chatroom = new Chatroom();

            // Create participants and register them
            Participant George = new Beatle("George");
            Participant Paul = new Beatle("Paul");
            Participant Ringo = new Beatle("Ringo");
            Participant John = new Beatle("John");
            Participant Yoko = 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");

        }
    }

    /// <summary>
    /// The 'Mediator' abstract class
    /// </summary>
    abstract class AbstractChatroom
    {
   
        public abstract void Register(Participant participant);
        public abstract void Send(string from, string to, string message);
    }

    /// <summary>
    /// The 'ConcreteMediator' class
    /// </summary>
    class Chatroom : AbstractChatroom
    {
   
        private Dictionary<string, Participant> _participants =
          new Dictionary<string, Participant>();

        public override void Register(Participant participant)
        {
   
            if (!_participants.ContainsValue(participant))
            {
   
                _participants[participant.Name] = participant;
            }

            participant.Chatroom = this;
        }

        public override void Send( string from, string to, string message)
        {
   
            Participant participant = _participants[to];

            if (participant != null)
            {
   
                participant.Receive(from, message);
            }
        }
    }

    /// <summary>
    /// The 'AbstractColleague' class
    /// </summary>
    class Participant
    {
   
        private Chatroom _chatroom;
        private string _name;

        // Constructor
        public Participant(string name)
        {
   
            this._name = name;
        }

        // Gets participant name
        public string Name
        {
   
            get {
    return _name; }
        }

        // Gets chatroom
        public Chatroom Chatroom
        {
   
            set {
    _chatroom = value; }
            get {
    return _chatroom; }
        }

        // Sends message to given participant
        public void Send(string to, string message)
        {
   
            _chatroom.Send(_name, to, message);
        }

        // Receives message from given participant
        public virtual void Receive(string from, string message)
        {
   
            Debug.Log(from + " to " + Name + ": '" + message + "'");
        }
    }

    /// <summary>
    /// A 'ConcreteColleague' class
    /// </summary>
    class Beatle : Participant
    {
   
        // Constructor
        public Beatle(string name)
          : base(name)
        {
   
        }

        public override void Receive(string from, string message)
        {
   
            Debug.Log("To a Beatle: ");
            base.Receive(from, message);
        }
    }

    /// <summary>
    /// A 'ConcreteColleague' class
    /// </summary>
    class NonBeatle : Participant
    {
   
        // Constructor
        public NonBeatle(string name)
          : base(name)
        {
   
        }

        public override void Receive(string from, string message)
        {
   
            Debug.Log("To a non-Beatle: ");
            base.Receive(from, message);
        }
    }
}

中介者模式案例2

复杂度 ***

/*
 * 它用于处理相关对象(同事)之间的通信  
 * 所有通信都由中介处理同事之间不需要互相了解
 * GOF:通过封装不同的对象集的方式允许松散耦合,相互互动和沟通。 
 * 允许操作每个对象集独立变化.  
 *
 **/

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

namespace MediatorExample2
{
   

    public class MediatorExample2 : MonoBehaviour
    {
   
	    void Start ( )
	    {
   
            StockMediator nyse = new StockMediator();

            // 重要的是:  
            //在这个例子中,它们可能没有什么不同,但是  
            //它们可以是完全不同的对象,并计算出不同的东西  
            //但是仍然能够以同样简单的方式与调解员交谈  
            //这就是为什么我们这里有不同的对象:  
            GormanSlacks broker = new GormanSlacks(nyse);
            JTPoorman broker2 = new JTPoorman(nyse);

            nyse.AddColleague(broker);
            nyse.AddColleague(broker2);

            // 因为它们调用同一个中介对象上的方法,所以它们与同一个中介进行通信  
            //他处理所有的股票交易,并保持跟踪。 所以经纪人自己  
            //彼此一无所知。 这是件好事:-)  
            broker.SaleOffer(Stock.MSFT, 100);
            broker.SaleOffer(Stock.GOOG, 50);

            broker2.BuyOffer(Stock.MSFT, 100);
            broker2.SaleOffer(Stock.NRG, 10);

            broker.BuyOffer(Stock.NRG, 10);
            broker.BuyOffer(Stock.NRG, 50);

            nyse.PrintStockOfferings();
        }


    }

    // I like using enums more than using strings
    // because it prevents typos and I don't need to remember strings ;)
    public enum Stock
    {
   
        MSFT,
        GOOG,
        NRG
    };


    public class StockOffer
    {
   
        public int stockShares {
    get; private set; }
        public Stock stock {
    get; private set; }
        public int colleagueCode {
    get; private set; }

        public StockOffer(int numOfShares, Stock stock, int collCode)
        {
   
            this.stockShares = numOfShares;
            this.stock = stock;
            this.colleagueCode = collCode;
        }
    }


    public abstract class Colleague
    {
   
        private Mediator mediator;
        private int colleagueCode;

        public Colleague(Mediator mediator)
        {
   
            this.mediator = mediator;
        }

        public void SetCode(int code)
        {
   
            colleagueCode = code;
        }

        public void SaleOffer(Stock stock, int shares)
        {
   
            mediator.SaleOffer(stock, shares, this.colleagueCode);
        }

        public void BuyOffer(Stock stock, int shares)
        {
   
            mediator.BuyOffer(stock, shares, this.colleagueCode);
        }
    }


    public class GormanSlacks : Colleague
    {
   
        // using : base() like here calls the constructor of the base class with the arguments passed in
        // here it calls "Colleague(Mediator mediator)"
        public GormanSlacks(Mediator mediator) : base(mediator)
        {
   
            Debug.Log("Gorman Slacks signed up with the stockexange");
        }
    }

    public class JTPoorman : Colleague
    {
   
        public JTPoorman(Mediator mediator) : base(mediator)
        {
   
            Debug.Log("JT Poorman signed up with the stockexange");
        }
    }






    public interface Mediator
    {
   
        void AddColleague(Colleague colleague);
        void SaleOffer(Stock stock, int shares, int code);
        void BuyOffer(Stock stock, int shares, int code);
    }


    public class StockMediator : Mediator
    {
   
        private List<Colleague> colleagues;
        private List<StockOffer> buyOffers;
        private List<StockOffer> sellOffers;

        private int colleagueCodes = 0;

        public StockMediator()
        {
   
            colleagues = new List<Colleague>();
            buyOffers = new List<StockOffer>();
            sellOffers = new List<StockOffer>();
        }

        #region Mediator implementation
        public void AddColleague(Colleague colleague)
        {
   
            this.colleagues.Add(colleague);
            colleagueCodes += 1;
            colleague.SetCode(colleagueCodes);
        }

        public void SaleOffer(Stock stock, int shares, int code)
        {
   
            bool stockSold = false;

            // see if someone is willing to buy:
            for (int i = 0; i < buyOffers.Count; i++)
            {
   
                StockOffer offer = buyOffers[i];
                // check if the stock is the same:
                if (offer.stock == stock && offer.stockShares == shares)
                {
   
                    Debug.Log(shares + " shares of " + stock + " stocks sold to colleague with code " + code);

                    buyOffers.Remove(offer);
                    stockSold = true;
                }

                if (stockSold) break;
            }

            if (!stockSold)
            {
   
                Debug.Log(shares + " shares of " + stock + " stocks added to inventory");
                StockOffer offer = new StockOffer(shares, stock, code);
                sellOffers.Add(offer);
            }
        }

        public void BuyOffer(Stock stock, int shares, int code)
        {
   
            bool stockBought = false;

            // see if someone is willing to buy:
            for (int i = 0; i < sellOffers.Count; i++)
            {
   
                StockOffer offer = sellOffers[i];
                // check if the stock is the same:
                if (offer.stock == stock && offer.stockShares == shares)
                {
   
                    Debug.Log(shares + " shares of " + stock + " stocks bought by colleague with code " + code);

                    sellOffers.Remove(offer);
                    stockBought = true;
                }

                if (stockBought) break;
            }

            if (!stockBought)
            {
   
                Debug.Log(shares + " shares of " + stock + " stocks added to inventory");
                StockOffer offer = new StockOffer(shares, stock, code);
                buyOffers.Add(offer);
            }
        }
        #endregion


        public void PrintStockOfferings()
        {
   
            Debug.Log("For Sale: " + sellOffers.Count);
            foreach (StockOffer offer in sellOffers)
            {
   
                Debug.Log(offer.stock + " - " + offer.stockShares + " - " + offer.colleagueCode);
            }

            Debug.Log("For Buy: " + buyOffers.Count);
            foreach (StockOffer offer in buyOffers)
            {
   
                Debug.Log(offer.stock + " - " + offer.stockShares + " - " + offer.colleagueCode);
            }
        }
    }

}

转载:https://blog.csdn.net/weixin_38531633/article/details/117431993
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场