陈雪彬
设计模式(十八)—— 中介者模式
来源:高培忠     发布时间: 2019-05-14      浏览次数:43

字号:

模式简介


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

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

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

结构分析


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);}//具体同事类Apublic 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); }}//具体同事类Bpublic 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(); }}

使用场景


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

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

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

  • 相关内容: