类关系图


类角色说明
1) 抽象中介者(Mediator)角色:抽象中介者角色定义统一的接口用于各同事角色之间的通信。
2) 具体中介者(Concrete Mediator)角色:具体中介者角色通过协调各同事角色实现协作行为。为此它要知道并引用各个同事角色。
3) 同事(Colleague)角色:每一个同事角色都知道对应的具体中介者角色,而且与其他的同事角色通信的时候,一定要通过中介者角色协作。
4)抽象同事角色

意图
用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。简单点来说,将原来两个直接引用或者依赖的对象拆开,在中间加入一个“中介”对象,使得两头的对象分别和“中介”对象引用或者依赖。

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

泡妞的例子
四个MM打麻将,相互之间谁应该给谁多少钱算不清楚了,幸亏当时我在旁边,先在我这里买筹码,打完了按照各自的筹码从我这里还钱,一切就OK啦,俺得到了四个MM的电话。

泡妞的代码
using System;
using System.Collections;
public abstract class Mediator 
{ 
    
public abstract void Pay(string frommm, string tomm,int count); 
}

public class ConcreteMediator:Mediator
{
    
private Hashtable ht;
    
public ConcreteMediator()
    
{
        ht
=new Hashtable();
    }

    
    
public void Add(MM mm)
    
{
        ht.Add(mm.Name,mm);
        mm.Mediator
=this;
    }

    
    
public override void Pay(string frommm, string tomm,int count)
    
{
        MM from
= ht[frommm] as MM;
        
//Console.WriteLine(from.Name);
        from.Send(tomm,count);
        MM to
= ht[tomm] as MM;
        to.Accept(frommm,count);
    }

}

public abstract class MM
{
    
protected int total;
    
public int Total
    
{
        
get{return total;}
        
set{total=value;}
    }

    
protected Mediator mediator;
    
public Mediator Mediator
    
{
        
get {return mediator;}
        
set{mediator=value;}
    }

    
protected string name;
    
public string Name
    
{
        
get{return name;}
        
set{name=value;}
    }

    
public MM(int Total,string name)
    
{
        
this.total=Total;
        
this.name=name;
    }

    
    
public abstract void Send(string to,int count);
    
public abstract void Accept(string from,int count);
}

public class RealMM:MM
{
    
public RealMM(int Total,string name):base(Total,name)
    
{
    }

    
public override void Send(string to,int count)
    
{
        total
-=count;
        Console.WriteLine(name
+"给了"+to+count.ToString());
    }

    
public override void Accept(string from,int count)
    
{
        total
+=count;
        Console.WriteLine(name
+"收到"+from+"给的"+count.ToString());
    }

}

public class MyClass
{
    
public static void Main()
    
{
        ConcreteMediator me
=new ConcreteMediator();
        RealMM Lucy
=new RealMM(100,"Lucy");
        RealMM Lily
=new RealMM(200,"Lily");
        RealMM Mary
=new RealMM(300,"Mary");
        me.Add(Lucy);
        me.Add(Lily);
        me.Add(Mary);
        
        Console.WriteLine(
"三缺一,斗地主好了!");
        Console.WriteLine(
"一阵大战后!");
        Console.WriteLine(
"清算中…………");
        me.Pay(
"Lily","Lucy",150);
        me.Pay(
"Mary","Lucy",50);
        Console.WriteLine(
"清算结束…………");
        Console.WriteLine(
"Lucy的余钱为"+Lucy.Total.ToString());
        Console.WriteLine(
"Lily的余钱为"+Lily.Total.ToString());
        Console.WriteLine(
"Mary的余钱为"+Mary.Total.ToString());
        RL();
    }

    
    
Helper methods
}



中介者模式
又称调停者模式。其包装了一系列对象相互作用的方式,使得这些对象不必相互明显作用。从而使他们可以松散偶合。当某些对象之间的作用发生改变时,不会立即影响其他的一些对象之间的作用。保证这些作用可以彼此独立的变化。调停者模式将多对多的相互作用转 化为一对多的相互作用。调停者模式将对象的行为和协作抽象化,把对象在小尺度的行为上与其他对象的相互作用分开处理。

备注
中介者的行为与要使用的数据与具体业务紧密相关,抽象中介者角色提供一个能方便很多对象使用的接口是不太现实的。所以抽象中介者角色往往是不存在的,或者只是一个标示接口。如果有幸能够提炼出真正带有行为的抽象中介者角色,我想同事角色对具体中介者角色的选择也是策略的一种应用。

当一个程序由许多类组成的时候,类之间的通信就非常复杂。中介者就是通过减少类之间的关联来解决这个问题。
在同事对象内部发生的时间会影响到其他所有同事,但是这种影响不会直接传到其他对象上,仅仅直接影响到中介者对象,而中介者对象反过来会协调其他的同事,形成整个系统的行为。

中介者模式与门面模式的不同:
门面模式是对一个对象子系统进行抽象,从而提供了一个更为方便的接口,它相当于提供了一个宏命令。它的协议是单向的,即门面对象对这个子系统提出请求,但反之不行。中介者为各对象提供了协作行为,而且协议是多向的。

posted on 2007-08-08 22:22  十分之七  阅读(657)  评论(3)    收藏  举报