设计模式(十八)—— 中介者模式

发布日期:2019-03-19

模式简介


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

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

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

结构分析


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("Hellohow are you?") colleagueB.Send("Finethank 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() }}

使用场景


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

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

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