注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

民主与科学

独立之人格,自由之思想

 
 
 

日志

 
 

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

2012-04-02 20:58:08|  分类: 设计模式 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
本文编辑整理自:
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) {
        }
    }
}


结束!
  评论这张
 
阅读(1261)| 评论(2)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017