设计模式之二十一:中介者模式(Mediator)

中介者模式:定义了一个对象。用来封装一系列对象的交互。中介者模式经过使对象之间没必要显式引用减小了对象之间的耦合,并且赞成你独立改变它们之间的交互。ios

中介者模式就是将对象之间的交互封装在了一个独立的对象中。这个独立的对象用来控制对象之间的交互行为,因此这个对象仍是蛮复杂的。ide

UML类图:
这里写图片描写叙述this

主要包含:spa

  1. Mediator:定义了一个Colleague对象之间交互的接口。
  2. ConcreteMediator:实现了Colleague对象之间的交互行为,并了解和能操做Colleague对象。
  3. Colleague classes:每一个Colleague都认识Mediator对象。并且经过Mediator来实现彼此之间的通信。

基础C++代码例如如下:code

#include <iostream>
#include <string>

using namespace std;

class Colleague;
class Mediator
{
    public:
    virtual void send(string message,Colleague * c)=0;

};


class Colleague
{
        public:
        Colleague(Mediator *m)
        {
            mediator=m;
        }
        void send(string message)
        {
            mediator->send(message,this);
        }
        virtual void notify(string message)=0;
        protected:
        Mediator * mediator;

};

class ConcreteColleague1:public Colleague
{
        public:
        ConcreteColleague1(Mediator * c):Colleague(c)
        {

        }
        void notify(string message)
        {
            cout<<"concreteColleague1 receive message:"<<message<<endl;
        }

};

class ConcreteColleague2:public Colleague
{
        public:
        ConcreteColleague2(Mediator *m):Colleague(m)
        {

        }
        void notify(string message)
        {
            cout<<"concreteColleague2 receive message:"<<message<<endl;
        }

};


class ConcreteMediator:public Mediator
{
    public:
    void send(string message,Colleague * c)
    {
        ConcreteColleague1* c1=dynamic_cast<ConcreteColleague1 *>(c);
        ConcreteColleague2* c2=dynamic_cast<ConcreteColleague2 *>(c);
        if(c1!=NULL)
        {
            cc2->notify(message);
        }

        if(c2!=NULL)
        {
            cc1->notify(message);
        }

    }

    void setCC1(ConcreteColleague1 * c)
    {
        cc1=c;
    }   
    void setCC2(ConcreteColleague2 * c)
    {
        cc2=c;
    }
    private:
    ConcreteColleague1 * cc1;
    ConcreteColleague2 * cc2;

};


int main()
{
    ConcreteMediator *m=new ConcreteMediator();
    ConcreteColleague1 * cc1=new ConcreteColleague1(m);
    ConcreteColleague2 * cc2=new ConcreteColleague2(m);

    m->setCC1(cc1);
    m->setCC2(cc2);

    cc1->send("how are you !");
    cc2->send("fine ,thank you");

    return 0;


}

运行输出:
这里写图片描写叙述对象


一个使用中介者模式的聊天室的样例。blog

这里实现了Mediator和Colleague的一对多的聚合关系。这种中介者模式才是有意义的使用方式。
UML类图:
这里写图片描写叙述接口

C++代码例如如下:图片

#include <iostream>
#include <map>
#include <string>


using namespace std;

class Participant;

class AbstractChatRoom
{
        public:
                virtual void registe(Participant * p)=0;
                virtual void send(string from,string to ,string message)=0;
};

class ChatRoom:public AbstractChatRoom
{
        public:
                void registe(Participant * p);

                void send(string from,string to ,string message);
        private:
                map<Participant *,string> participants;

};


class Participant
{
        public:
                Participant(string n=""):name(n)
                {

                }

                string getName()
                {
                    return name;
                }
                void setChatRoom(ChatRoom *c)
                {
                    chatRoom=c;
                }
                void send(string to,string message)
                {
                    chatRoom->send(name,to,message);
                }

                virtual void receive(string from,string message)
                {
                    cout<<from<<" to "<<name<<" : "<<message<<endl;
                }
        private:
                string name;
                ChatRoom * chatRoom;

};


void ChatRoom::registe(Participant * p)
                {
                    if(!participants.count(p))
                    {
                        participants.insert(pair<Participant *,string>(p,p->getName()));
                    }
                    p->setChatRoom(this);
                }


                void ChatRoom::send(string from,string to ,string message)
                {
                    map<Participant *,string>::iterator iter;
                    for(iter=participants.begin();iter!=participants.end();iter++)
                    {
                        if(iter->second==to)
                                break;
                    }
                    if(iter!=participants.end())
                    {
                        iter->first->receive(from,message);
                    }
                }




class Beatle:public Participant
{
        public:
                Beatle(string n=""):Participant(n)
                {

                }
                void receive(string from,string message)
                {
                    cout<<"to a beatle : ";
                    Participant::receive(from,message);
                }

};

class NonBeatle:public Participant
{
        public:
                NonBeatle(string n=""):Participant(n)
                {

                }
                void receive(string from,string message)
                {
                    cout<<"to a non-beatle : ";
                    Participant::receive(from,message);
                }

};


int main()
{
    cout<<"聊天室中介者模式代码"<<endl;
    ChatRoom * chatRoom=new ChatRoom();

    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->registe(george);
    chatRoom->registe(paul);
    chatRoom->registe(ringo);
    chatRoom->registe(john);
    chatRoom->registe(yoko);


    yoko->send("John","hi John!");
    paul->send("Ringo","All you need is love");
    ringo->send("George","My sweet Lord");
    paul->send("John","can not buy me love");
    john->send("Yoko","My sweet love");

    return 0;
}

运行输出:
这里写图片描写叙述ip