设计模式之Mediator(中介者)模式(应用篇)

本文编辑整理自:
http://blog.csdn.net/haiyan0106/article/details/1651719
一、什么是中介者模式
     Mediator模式也叫中介者模式,是由GoF提出的23种软件设计模式的一种。Mediator模式是行为模式之一,在Mediator模式中,类之间的交互行为被统一放在Mediator的对象中,对象通过Mediator对象同其他对象交互,Mediator对象起着控制器的作用。
关于 Mediator模式的更多理论知识请参考《 设计模式之Mediator(中介者)模式(理论篇)
二、何时使用中介者模式
    各个对象之间的交互操作非常多,每个对象的行为操作都依赖彼此对方,修改一个对象的行为,同时会涉及到修改很多其他对象的行为,如果使用Mediator模式,可以使各个对象间的耦合松散,只需关心和 Mediator的关系,使多对多的关系变成了一对多的关系,可以降低系统的复杂性,提高可修改扩展性。
在下列情况下使用中介者模式:
1、一组对象以定义良好但是复杂的方式进行通信。产生的相互依赖关系结构混乱且难以理解。
2、一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象。
3、想定制一个分布在多个类中的行为,而又不想生成太多的子类。

三、举例
    Mediator模式是GoF的23种设计模式中较为容易理解的一个,我们在平时的应用中也会经常用到,但可能不会有意去抽象出一个完整的Mediator类,因为要设计一个可复用又可扩展的Mediator是很不容易的。
  Mediator模式的主要作用在于为多个对象之间的交互提供一种媒介,以简化对象之间的耦合关系。下面用两个实例来说明Mediator模式的应用。

3.1、ChatRoom(聊天室)示例
   聊天室大家想必都知道,在下面的示例中,我们尝试实现一个布告栏式的ChatRoom,任何人想要发送消息给其他人,只需将消息发送给ChatRoom对象,由ChatRoom负责数据的转发,而不是直接与消息的接收者交互。后面的笔记中将从Observer模式的角度来解决ChatRoom问题。
#include <iostream>
#include <string>
#include <map>
using namespace std ;

class
 Participant ;

// "AbstractMediator"
struct IChatroom
{

  // Methods
  virtual  void Register ( Participant * participant  ) =  0 ;
  virtual
 void Send ( string & from , string & to , string & message  ) =  0 ;
};


// "AbstractColleague"
class Participant
{

    friend class
 Chatroom ;
    // Fields
private :
    IChatroom * pChatroom ;
    string name ;

    // Constructors
public :
    /*Participant()
    {
    }*/


    Participant (  const  char * name  )
    {

        this
->name  = name ;
    }


    virtual
 ~Participant ()
    {
    }


    // Methods
    virtual  void Send ( string & to , string & message  )
    {

        pChatroom ->Send ( name , to , message  );
    }


    virtual
 void Receive ( string & from , string & message  )
    {

        cout  << from .c_str () <<  " to "  << name .c_str () <<  " : ["  << message .c_str () <<  "]"  << endl ;
    }
};


// More ConcreteColleague, omitted...

// "ConcreteMediator"
class Chatroom  :  public IChatroom
{

    // Fields
private :
    map <string , Participant *> mapParticipants ;     // nickname to Participant map

    // Methods
public :
    void
 Register ( Participant * pParticipant  )
    {

        mapParticipants [ pParticipant ->name  ] = pParticipant ;

        pParticipant ->pChatroom  =  this ;
    }


    void
 Send ( string & from , string & to , string & message  )
    {

        map <string , Participant *>::iterator ptr ;
        ptr  = mapParticipants .find (to );
        if
 ( ptr  != mapParticipants .end () )
        {

            Participant * pto  = (*ptr ).second ;
            pto ->Receive ( from , message  );
        }
    }
};


int
 main ()
{

    // Create chatroom
    Chatroom c ;

    // Create 'chatters' and register them
    Participant George ( "George" );
    Participant Paul ( "Paul" );
    Participant Ringo ( "Ringo" );

    c .Register ( &George  );
    c .Register ( &Paul  );
    c .Register ( &Ringo  );

    // Chatting participants
    George .Send ( string ( "Paul" ), string ( "Hi Paul!" ) );
    Paul .Send ( string ( "Ringo" ), string ( "Good Morning!" ) );
    Ringo .Send ( string ( "George" ), string ( "Hi Friend!" ) );

    return
 0 ;
}

3.2、多线程Producer-Consumer(生产者和消费者示例)
   以下是一个多线程Producer-Comsumer的例子,在该示例中,由于无法在多个Producer、Cosumer之间建立直接的联系,因此,通过Mediator类来完成这种信息交互,当Producer要Produce时,只需与Mediator进行交互,以查询是否有空的Slot可供存放Product,而Comsumer要Comsume时,也只需与Mediator进行交互,以查询是否有Product可供Comsume。
以下是该示例的Java实现:
import java .util .*;
class
 Product  {
    int
 id ;

    Product ( int id ) {
        this
.id  = id ;
    }
}


class
 Mediator  {
    private
 boolean stopFlag  = false;

    private
 Stack slot  =  new Stack ();

    private
 int slotCount ;

    public
 Mediator ( int slotCount ) {
        this
.slotCount  = slotCount ;
    }


    public
 boolean stop () {
        return
 stopFlag ;
    }


    public
 void stop (boolean flag ) {
        stopFlag  = true;
    }


    public
 boolean put (Product product ) {
        synchronized ( slot  ) {     // or synchronized on Mediator.class, but on slot is better and reasonable
            if  ( slot .size () >= slotCount  ) {
                return
 false;
            }


            slot .push ( product  );
        }


        return
 true;
    }


    public
 Product get () {
        synchronized ( slot  ) {
            if
 ( slot .empty () )
                return
 null ;

            Product product  = (Product )slot .pop ();

            return
 product ;
        }
    }
}


class
 Producer extends Thread  {
    private
 Mediator med ;

    private
 int id ;

    private static
 int num  =  1 ;

    public
 Producer (Mediator m ) {
        med  = m ;
        id  = num ++;
    }


    public
 void run () {
        Product product ;
        while
 ( !med .stop () ) {
            product  =  new Product (( int ) (Math .random () *  100 ));
            synchronized  (System .out ) {
                System .out .println ( "Producer["  + id  +  "] produces Product["
                    +
 product .id  +  "]" );
            }

            while
 ( !med .stop () && !med .put (product ) ) {  // if put failed, try to put again and again.
                try  {
                    sleep (  100  );
                }
 catch  (InterruptedException ie ) {
                }
            }


            try
 {
                sleep (  100  );
            }
 catch  (InterruptedException ie ) {
            }
        }
    }
}


class
 Consumer extends Thread  {
    private
 Mediator med ;

    private
 int id ;

    private static
 int num  =  1 ;

    public
 Consumer (Mediator m ) {
        med  = m ;
        id  = num ++;
    }


    public
 void run () {
        Product product ;
        while
 ( !med .stop () ) {
            product  = med .get ();
            if
 ( product  != null  ) {
                synchronized  (System .out ) {
                    System .out .println ( "Consumer["  + id  +  "] is consuming Product["
                        +
 product .id  +  "]" );
                }
            }

            try
 {
                sleep (  100  );
            }
 catch  (InterruptedException ie ) {
            }
        }
    }
}


class
 MediatorDemo  {
    public static
 void  main (String [] args ) {
        Mediator med  =  new Mediator ( 2 );
        Thread thread [] = {  new Producer (med ),  new Producer (med ),
                new
 Consumer (med ),  new Consumer (med ),  new Consumer (med ) };

        for
 ( int i  =  0 ; i  < thread .length ; i ++)
            thread [i ].start ();

        // before stop all threads, sleep 1 second
        try  {
            Thread .sleep ( 1000 );
        }
 catch  (InterruptedException ie ) {
        }


        med .stop (true);
        // Wait for all threads to return
        try  {
            for
 ( int i  =  0 ; i  < thread .length ; i ++) {
                thread [i ].join ();
            }
        }
 catch  (InterruptedException ie ) {
        }
    }
}


结束!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值