设计模式之Mediator中介者模式

 

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

适用性:

  • 一组对象以定义良好但是复杂的方式进行通信。产生的相互依赖关系结构混乱且难以理解。
  • 一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象。
  • 想定制一个分布在多个类中的行为,而又不想生成太多的子类。

DefinitionDefine an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.

participants

    The classes and/or objects participating in this pattern are:

  • Mediator  (IChatroom)
    • defines an interface for communicating with Colleague objects
  • ConcreteMediator  (Chatroom)
    • implements cooperative behavior by coordinating Colleague objects
    • knows and maintains its colleagues
  • Colleague classes  (Participant)
    • each Colleague class knows its Mediator object
    • each colleague communicates with its mediator whenever it would have otherwise communicated with another colleague

Mediator中介者模式,在软件构建过程中,经常会出现多个对象互相关联交互的情况,对象之间常常会维持一种复杂的引用关系,如果遇到一些需求的更改,这种直接的引用关系将面临不断的变化。使用一个中介对象来管理对象间的关联关系,避免相互交互的对象之间的紧耦合引用关系,从而更好地抵御变化。

将多个对象间复杂的关联关系解耦,mediator模式将多个对象间的控制逻辑进行集中管理,变多个对象互相关联为多个对象和一个中介者关联,简化了系统的维护,抵御了可能的变化。随着控制逻辑的复杂化,mediator具体对象的实现可能相当复杂。这时候可以对mediator对象进行分解处理。Façade模式是解耦系统外到系统内(单向)的对象关联关系;mediator模式是解耦系统内各个对象之间(双向)的关联关系。

 

Sample code in c#

This structural code demonstrates the Mediator pattern facilitating loosely coupled communication between different objects and object types. The mediator is a central hub through which all interaction must take place.

// Mediator pattern -- Structural example

 

using System;
using System.Collections;

namespace DoFactory.GangOfFour.Mediator.Structural
{

  // Mainapp test application

  class MainApp
  {
    static void Main()
    {
      ConcreteMediator m = new ConcreteMediator();

      ConcreteColleague 1 c 1 = new ConcreteColleague1(m);
      ConcreteColleague 2 c 2 = new ConcreteColleague2(m);

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

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

      // Wait for user
      Console.Read();
    }
  }

  // "Mediator"

  abstract class Mediator
  {
    public abstract void Send(string message,
      Colleague colleague);
  }

  // "ConcreteMediator"

  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);
      }
    }
  }

  // "Colleague"

  abstract class Colleague
  {
    protected Mediator mediator;

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

  // "ConcreteColleague1"

  class ConcreteColleague1 : Colleague
  {
    // Constructor
    public ConcreteColleague1(Mediator mediator)
      : base(mediator)
    {
    }

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

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

  // "ConcreteColleague2"

  class ConcreteColleague2 : Colleague
  {
    // Constructor
    public ConcreteColleague2(Mediator mediator)
      : base(mediator)
    {
    }

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

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

 

Output

Colleague2 gets message: How are you?

Colleague1 gets message: Fine, thanks

 

This real-world code demonstrates the Mediator pattern facilitating loosely coupled communication between different Participants registering with a Chatroom. The Chatroom is the central hub through which all communication takes place. At this point only one-to-one communication is implemented in the Chatroom, but would be trivial to change to one-to-many.

// Mediator pattern -- Real World example

 

using System;
using System.Collections;

namespace DoFactory.GangOfFour.Mediator.RealWorld
{
  
  // MainApp test application

  class MainApp
  {
    static void Main()
    {
      // 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") ;

      // Wait for user
      Console.Read();
    }
  }

  // "Mediator"

  abstract class AbstractChatroom
  {
    public abstract void Register(Participant participant);
    public abstract void Send(
      string from, string to, string message);
  }

  // "ConcreteMediator"

  class Chatroom : AbstractChatroom
  {
    private Hashtable participants = new Hashtable();

    public override void Register(Participant participant)
    {
      if (participants[participant.Name] == null)
      {
        participants[participant.Name] = participant;
      }

      participant.Chatroom = this;
    }

    public override void Send(
      string from, string to, string message)
    {
      Participant pto = (Participant)participants[to];
      if (pto != null)
      {
        pto.Receive(from, message);
      }
    }
  }

  // "AbstractColleague"

  class Participant
  {
    private Chatroom chatroom;
    private string name;

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

    // Properties
    public string Name
    {
      get{ return name; }
    }

    public Chatroom Chatroom
    {
      set{ chatroom = value; }
      get{ return chatroom; }
    }

    public void Send(string to, string message)
    {
      chatroom.Send(name, to, message);
    }

    public virtual void Receive(
      string from, string message)
    {
      Console.WriteLine("{0} to {1}: '{2}'",
        from, Name, message);
    }
  }

  //" ConcreteColleague1"

  class Beatle : Participant
  {
    // Constructor
    public Beatle(string name) : base(name)
    {
    }

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

  //" ConcreteColleague2"

  class NonBeatle : Participant
  {
    // Constructor
    public NonBeatle(string name) : base(name)
    {
    }

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

 

Output

To a Beatle: Yoko to John: 'Hi John!'

To a Beatle: Paul to Ringo: 'All you need is love'

To a Beatle: Ringo to George: 'My sweet Lord'

To a Beatle: Paul to John: 'Can't buy me love'

To a non-Beatle: John to Yoko: 'My sweet love'

 

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值