设计模式学习总结-中介者模式(Mediator Method)

问题:
在面向对象系统的设计和开发过程中,对象之间的交互和通信是最为常见的情况。在系统比较小的时候,可能对象间的通信不是很多、对象也比较少,我

们可以直接硬编码到各个对象的方法中。但是当系统规模很大,需要通讯的对象很多,这种硬编码的形式,就会造成系统对象相互交错依赖(如当我们完

成某种操作时,同时要改变对象B的结果,又要将结果传给C对象,C有可能接收改变后影响D对象...),每个对象与相互通信的对象之间都要维护一个引

用,对象间的通信也变得越来越复杂,有没有一种办法可以使各个对象间的通信不必显势去声明和引用,来降低了系统的复杂性能并降低各个对象之间的

紧耦合?
定义:
中介者模式(Mediator Pattern)是一种行为模式,定义一个中介对象来封装系列对象之间的交互。中介者使各个对象不需要显示地相互引用,从而使其

耦合性松散,而且可以独立地改变他们之间的交互。
意图:
Mediator模式中,每个Colleague维护一个Mediator的引用,当同事类需要交互时,可以通过Concrete Mediator提供的交互方法来处理,Concrete

Mediator接收发送消息类传递的消息,并调用接收类的方法接收消息,交互的同事类不必维护对各自的引用,甚至它们也不知道各个的存在。Mediator模

式通过这种方式将多对多的通信简化为了一(Mediator)对多(Colleague)的通信。
参与者:
•抽象中介者(Mediator)角色:
定义了同事对象交互的接口。
•具体中介者对象(ConcreteMediator)角色:
实现抽象类中的方法,此具体中介者对象需要知道所有具体同事类,并从具体同事接受消息,向具体同事对象发送命令。
•抽象同事(Colleague)角色:
定义了具体同事角色的公用接口。 每个同事类的行为分为两种:第一种是同事角色本身的行为,不与其他同事角色或中介者交互的方法,这种方法叫做

自发行为(Self-Method);第二种是必须依赖中介者才能完成的行为,叫做依赖方法(Dep-Method)。
具体同事类(ConcreteColleague)角色:具体同事角色,实现抽象同事类中的方法。每一个同时类需要知道中介者对象;每个具体同事类只需要了解自

己的行为,而不需要了解其他同事类的情况。

UML:


代码说明:

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

/// <summary>
/// The 'ConcreteMediator' class
/// </summary>
class ConcreteMediator : MediatorClass
{
    //维护了相互通信对象的引用
    private ConcreteColleagueB _colleague1;
    private ConcreteColleagueA _colleague2;

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

    public ConcreteColleagueA Colleague2
    {
        set { _colleague2 = value; }
    }
    /// <summary>
    
/// 对象间通讯方法
    
/// </summary>
    
/// <param name="message"></param>
    
/// <param name="colleague"></param>
    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 MediatorClass mediator;
    // Constructor
    public Colleague(MediatorClass mediator)
    {
        this.mediator = mediator;
    }
}

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

    public void Send(string message)
    {
        mediator.Send(message, this);
    }
    public void Notify(string message)
    {
        Console.WriteLine("ColleagueA gets message: " + message);
    }
}

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

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

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

}
void Mediator1Test(string[] args)
{

    ConcreteMediator m = new ConcreteMediator();
    ConcreteColleagueB c1 = new ConcreteColleagueB(m);
    ConcreteColleagueA c2 = new ConcreteColleagueA(m);
    m.Colleague1 = c1;
    m.Colleague2 = c2;
    c1.Send("How are you? JamesHao");            
    c2.Send("Fine, thanks");
    // Wait for user
    Console.ReadKey();

}

 

实例说明:

诺基亚手机工厂
聊天室多人(多个对象)聊天通讯代码

uml图如下: 

代码:  

/// <summary>
/// The 'Mediator' abstract class
/// </summary>
abstract class AbstractChatroom
{
    public abstract void Register(Participant participant);
    public abstract void Send(string fromstring 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 fromstring to, string message)
    {
        Participant participant = _participants[to];
        if (participant != null)
        {
            participant.Receive(from, message);
        }

    }

}

/// <summary>
/// 参与者Participant类
/// </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 fromstring message)
    {
        Console.WriteLine("{0} to {1}: '{2}'"from, Name, message);
    }
}
void Mediator2Test()
{
    // Create chatroom
    Chatroom chatroom = new Chatroom();

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


优点:
•中介者模式的优点是减少了类之间的依赖,使原有一对多的依赖变成了一对一的依赖,同事类只依赖中介者,降低了类之间的耦合。
缺点:
•中介者模式的缺点是中介者会膨胀的很大,而且逻辑复杂,同事类越多,中介者逻辑越复杂。
应用场景:
•一组对象以定义良好但是复杂的方式进行通信。产生的相互依赖关系结构混乱且难以理解。
•一个对象引用很多其他对象并直接与这些对象通信,导致难以复用该对象。
•想定制一个分部在多个类中的行为,而又不想生成太多的子类。 

posted @ 2012-08-01 18:59  ejiyuan  阅读(1629)  评论(4编辑  收藏  举报