zoukankan      html  css  js  c++  java
  • 设计模式(十八)—— 中介者模式

    模式简介


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

    通常情况下,应用程序由许多类组成,随着类数量不断增加,系统变得难以维护,主要体现在类之间的交互变得更加复杂,难以理解,修改其中一个类可能会影响到其他的类,导致整个系统崩溃。

    想象机场控制塔控制飞机起飞降落的过程,飞机降落前先与机场控制塔通信,控制塔通知其它飞机暂时不要降落,跑道已经被占用了。这是一个典型的中介者模式,飞机间的通信统一通过机场控制塔,而不是各自进行通信,当某架飞机希望降落时,只需要通过控制塔,不用直接通知其它等待降落的飞机。

    结构分析


    UML类图

    角色说明

    • Mediator

    抽象中介者。定义一个接口,用于同事类之间的通信。

    • ConcreteMediator

    具体中介者,了解并维护各个同事,协调同事对象实现协作。

    • Colleague

    抽象同事类

    • ConcreteColleague

    具体同事类,通过中介者与其它同事进行通信。

    工作原理

    同事向中介者对象发送和接受请求,中介者在各同事间适当地转发请求以实现协作行为。

    结构代码

    //抽象中介者
    public interface IMediator
    {
        void SendMessage(string message, Colleague colleague);
    }
    
    //具体中介者
    public class ConcreteMediator : IMediator
    {
        public ConcreteColleagueA ConcreteColleagueA { get; set; }
        public ConcreteColleagueB ConcreteColleagueB { get; set; }
        public void SendMessage(string message, Colleague colleague)
        {
            if (colleague == ConcreteColleagueA)
            {
                ConcreteColleagueB.Receive(message);
            }
            else
            {
                ConcreteColleagueA.Receive(message);
            }
        }
    }
    
    //抽象同事类
    public abstract class Colleague
    {
        protected IMediator _mediator;
        public Colleague(IMediator mediator)
        {
            this._mediator = mediator;
        }
    
        public abstract void Send(string message);
        public abstract void Receive(string message);
    }
    
    //具体同事类A
    public class ConcreteColleagueA : Colleague
    {
        public ConcreteColleagueA(IMediator mediator) : base(mediator)
        {
        }
    
        public override void Receive(string message)
        {
            Console.WriteLine($"ConcreteColleagueA Receive Message:{message}");
        }
    
        public override void Send(string message)
        {
            Console.WriteLine($"ConcreteColleagueA Send Message:{message}");
            _mediator.SendMessage(message, this);
        }
    }
    
    //具体同事类B
    public class ConcreteColleagueB : Colleague
    {
        public ConcreteColleagueB(IMediator mediator) : base(mediator)
        {
        }
    
        public override void Receive(string message)
        {
            Console.WriteLine($"ConcreteColleagueB Receive Message:{message}");
        }
    
        public override void Send(string message)
        {
            Console.WriteLine($"ConcreteColleagueB Send Message:{message}");
            _mediator.SendMessage(message, this);
        }
    }
    

    客户端调用

    static void Main(string[] args)
    {
        ConcreteMediator mediator = new ConcreteMediator();
        ConcreteColleagueA colleagueA = new ConcreteColleagueA(mediator);
        ConcreteColleagueB colleagueB = new ConcreteColleagueB(mediator);
    
        mediator.ConcreteColleagueA = colleagueA;
        mediator.ConcreteColleagueB = colleagueB;
    
        colleagueA.Send("Hello,how are you?");
        colleagueB.Send("Fine,thank you.And you?");
        Console.ReadLine();
    }
    

    输出结果:

    示例分析


    本节讲述飞机之间通过控制塔进行通信的示例。首先创建控制塔类ControlTower,这里省略了抽象中介者。

    public class ControlTower
    {
        private Dictionary<string, AbstractPlane> _planes = new Dictionary<string, AbstractPlane>();
    
        public void Register(AbstractPlane plane)
        {
            if (!_planes.ContainsValue(plane))
            {
                _planes[plane.Name] = plane;
            }
    
            plane.ControlTower = this;
        }
    
        public void SendMessage(string from, string to, string message)
        {
            if (_planes.ContainsKey(to))
            {
                _planes[to].Receive(from, message);
            }
        }
    }
    

    声明抽象同事类AbstractPlane,并实现具体同时类AirLiner。

    public abstract class AbstractPlane
    {
        protected string _name;
        public AbstractPlane(string name)
        {
            _name = name;   
        }
    
        public ControlTower ControlTower { get; set; }
        public string Name
        {
            get { return _name; }
        }
        public abstract void Send(string to, string message);
        public abstract void Receive(string from, string message);
    }
    
    public class Airliner : AbstractPlane
    {
        public Airliner(string name) : base(name)
        {
        }
    
        public override void Receive(string from, string message)
        {
            Console.WriteLine($"{this.Name} Receive Message:{message} from {from}");
        }
    
        public override void Send(string to, string message)
        {
            ControlTower.SendMessage(this.Name, to, message);
        }
    }
    

    客户端调用,向控制塔对象注册5架飞机,airLinerA通过控制塔对象与airLinerB进行通讯。

    class Program
    {
        static void Main(string[] args)
        {
            ControlTower tower = new ControlTower();
            Airliner airLinerA = new Airliner("A");
            Airliner airLinerB = new Airliner("B");
            Airliner airLinerC = new Airliner("C");
            Airliner airLinerD = new Airliner("D");
            Airliner airLinerE = new Airliner("E");
    
            tower.Register(airLinerA);
            tower.Register(airLinerB);
            tower.Register(airLinerC);
            tower.Register(airLinerD);
            tower.Register(airLinerE);
    
            airLinerA.Send("B","When will you arrive?");
            airLinerB.Send("A", "Already landed.");
            Console.ReadLine();
        }
    }
    

    使用场景


    • 一组对象以定义良好但是复杂的方式进行通信。产生的相互依赖关系结构混乱且难以理解。

    • 一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象。

    • 想定制一个分布在多个类中的行为,而又不想生成太多的子类。

  • 相关阅读:
    Vue框架之基础知识
    Vue框架之初识
    Django组件之modelformset
    Django之小结
    Django组件之modelform
    Django之form表单详解
    jquery基础知识2
    jQuery基础知识1
    js基础知识4
    js基础知识3
  • 原文地址:https://www.cnblogs.com/Answer-Geng/p/9287914.html
Copyright © 2011-2022 走看看