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

中介者模式:定义了一个对象。用来封装一系列对象的交互。中介者模式通过使对象之间不必显式引用减少了对象之间的耦合,而且同意你独立改变它们之间的交互。

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

UML类图:

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

主要包含:

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

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

<span class="hljs-preprocessor">#include <iostream></iostream></span>
<span class="hljs-preprocessor">#include <string></string></span>

<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;

<span class="hljs-keyword">class</span> Colleague;
<span class="hljs-keyword">class</span> Mediator
{
    <span class="hljs-keyword">public</span>:
    <span class="hljs-keyword">virtual</span> <span class="hljs-keyword">void</span> send(<span class="hljs-built_in">string</span> message,Colleague * c)=<span class="hljs-number">0</span>;

};

<span class="hljs-keyword">class</span> Colleague
{
        <span class="hljs-keyword">public</span>:
        Colleague(Mediator *m)
        {
            mediator=m;
        }
        <span class="hljs-keyword">void</span> send(<span class="hljs-built_in">string</span> message)
        {
            mediator->send(message,<span class="hljs-keyword">this</span>);
        }
        <span class="hljs-keyword">virtual</span> <span class="hljs-keyword">void</span> notify(<span class="hljs-built_in">string</span> message)=<span class="hljs-number">0</span>;
        <span class="hljs-keyword">protected</span>:
        Mediator * mediator;

};

<span class="hljs-keyword">class</span> ConcreteColleague1:<span class="hljs-keyword">public</span> Colleague
{
        <span class="hljs-keyword">public</span>:
        ConcreteColleague1(Mediator * c):Colleague(c)
        {

        }
        <span class="hljs-keyword">void</span> notify(<span class="hljs-built_in">string</span> message)
        {
            <span class="hljs-built_in">cout</span><<<span class="hljs-string">"concreteColleague1 receive message:"</span><<message<<endl; } }; <span class="hljs-keyword">class ConcreteColleague2:<span class="hljs-keyword">public</span> Colleague
{
        <span class="hljs-keyword">public</span>:
        ConcreteColleague2(Mediator *m):Colleague(m)
        {

        }
        <span class="hljs-keyword">void</span> notify(<span class="hljs-built_in">string</span> message)
        {
            <span class="hljs-built_in">cout</span><<<span class="hljs-string">"concreteColleague2 receive message:"</span><<message<<endl; } }; <span class="hljs-keyword">class ConcreteMediator:<span class="hljs-keyword">public</span> Mediator
{
    <span class="hljs-keyword">public</span>:
    <span class="hljs-keyword">void</span> send(<span class="hljs-built_in">string</span> message,Colleague * c)
    {
        ConcreteColleague1* c1=<span class="hljs-keyword">dynamic_cast</span><concretecolleague1 *>(c);
        ConcreteColleague2* c2=<span class="hljs-keyword">dynamic_cast</span><concretecolleague2 *>(c);
        <span class="hljs-keyword">if</span>(c1!=NULL)
        {
            cc2->notify(message);
        }

        <span class="hljs-keyword">if</span>(c2!=NULL)
        {
            cc1->notify(message);
        }

    }

    <span class="hljs-keyword">void</span> setCC1(ConcreteColleague1 * c)
    {
        cc1=c;
    }
    <span class="hljs-keyword">void</span> setCC2(ConcreteColleague2 * c)
    {
        cc2=c;
    }
    <span class="hljs-keyword">private</span>:
    ConcreteColleague1 * cc1;
    ConcreteColleague2 * cc2;

};

<span class="hljs-keyword">int</span> main()
{
    ConcreteMediator *m=<span class="hljs-keyword">new</span> ConcreteMediator();
    ConcreteColleague1 * cc1=<span class="hljs-keyword">new</span> ConcreteColleague1(m);
    ConcreteColleague2 * cc2=<span class="hljs-keyword">new</span> ConcreteColleague2(m);

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

    cc1->send(<span class="hljs-string">"how are you !"</span>);
    cc2->send(<span class="hljs-string">"fine ,thank you"</span>);

    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;

}
</concretecolleague2></concretecolleague1></message<<endl;></message<<endl;>

运行输出:

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

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

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

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

C++代码例如以下:

<span class="hljs-preprocessor">#include <iostream></iostream></span>
<span class="hljs-preprocessor">#include <map></map></span>
<span class="hljs-preprocessor">#include <string></string></span>

<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;

<span class="hljs-keyword">class</span> Participant;

<span class="hljs-keyword">class</span> AbstractChatRoom
{
        <span class="hljs-keyword">public</span>:
                <span class="hljs-keyword">virtual</span> <span class="hljs-keyword">void</span> registe(Participant * p)=<span class="hljs-number">0</span>;
                <span class="hljs-keyword">virtual</span> <span class="hljs-keyword">void</span> send(<span class="hljs-built_in">string</span> from,<span class="hljs-built_in">string</span> to ,<span class="hljs-built_in">string</span> message)=<span class="hljs-number">0</span>;
};

<span class="hljs-keyword">class</span> ChatRoom:<span class="hljs-keyword">public</span> AbstractChatRoom
{
        <span class="hljs-keyword">public</span>:
                <span class="hljs-keyword">void</span> registe(Participant * p);

                <span class="hljs-keyword">void</span> send(<span class="hljs-built_in">string</span> from,<span class="hljs-built_in">string</span> to ,<span class="hljs-built_in">string</span> message);
        <span class="hljs-keyword">private</span>:
                <span class="hljs-stl_container"><span class="hljs-built_in">map</span><participant *,<span class="hljs-built_in">string</participant></span>> participants;

};

<span class="hljs-keyword">class</span> Participant
{
        <span class="hljs-keyword">public</span>:
                Participant(<span class="hljs-built_in">string</span> n=<span class="hljs-string">""</span>):name(n)
                {

                }

                <span class="hljs-built_in">string</span> getName()
                {
                    <span class="hljs-keyword">return</span> name;
                }
                <span class="hljs-keyword">void</span> setChatRoom(ChatRoom *c)
                {
                    chatRoom=c;
                }
                <span class="hljs-keyword">void</span> send(<span class="hljs-built_in">string</span> to,<span class="hljs-built_in">string</span> message)
                {
                    chatRoom->send(name,to,message);
                }

                <span class="hljs-keyword">virtual</span> <span class="hljs-keyword">void</span> receive(<span class="hljs-built_in">string</span> from,<span class="hljs-built_in">string</span> message)
                {
                    <span class="hljs-built_in">cout</span><<from<<<span class="hljs-string">" to "<<name<<<span class="hljs-string">" : "<<message<<endl; } <span class="hljs-keyword">private:
                <span class="hljs-built_in">string</span> name;
                ChatRoom * chatRoom;

};

<span class="hljs-keyword">void</span> ChatRoom::registe(Participant * p)
                {
                    <span class="hljs-keyword">if</span>(!participants.count(p))
                    {
                        participants.insert(pair<participant *,<span class="hljs-built_in">string>(p,p->getName()));
                    }
                    p->setChatRoom(<span class="hljs-keyword">this</span>);
                }

                <span class="hljs-keyword">void</span> ChatRoom::send(<span class="hljs-built_in">string</span> from,<span class="hljs-built_in">string</span> to ,<span class="hljs-built_in">string</span> message)
                {
                    <span class="hljs-stl_container"><span class="hljs-built_in">map</span><participant *,<span class="hljs-built_in">string</participant></span>>::iterator iter;
                    <span class="hljs-keyword">for</span>(iter=participants.begin();iter!=participants.end();iter++)
                    {
                        <span class="hljs-keyword">if</span>(iter->second==to)
                                <span class="hljs-keyword">break</span>;
                    }
                    <span class="hljs-keyword">if</span>(iter!=participants.end())
                    {
                        iter->first->receive(from,message);
                    }
                }

<span class="hljs-keyword">class</span> Beatle:<span class="hljs-keyword">public</span> Participant
{
        <span class="hljs-keyword">public</span>:
                Beatle(<span class="hljs-built_in">string</span> n=<span class="hljs-string">""</span>):Participant(n)
                {

                }
                <span class="hljs-keyword">void</span> receive(<span class="hljs-built_in">string</span> from,<span class="hljs-built_in">string</span> message)
                {
                    <span class="hljs-built_in">cout</span><<<span class="hljs-string">"to a beatle : "</span>;
                    Participant::receive(from,message);
                }

};

<span class="hljs-keyword">class</span> NonBeatle:<span class="hljs-keyword">public</span> Participant
{
        <span class="hljs-keyword">public</span>:
                NonBeatle(<span class="hljs-built_in">string</span> n=<span class="hljs-string">""</span>):Participant(n)
                {

                }
                <span class="hljs-keyword">void</span> receive(<span class="hljs-built_in">string</span> from,<span class="hljs-built_in">string</span> message)
                {
                    <span class="hljs-built_in">cout</span><<<span class="hljs-string">"to a non-beatle : "</span>;
                    Participant::receive(from,message);
                }

};

<span class="hljs-keyword">int</span> main()
{
    <span class="hljs-built_in">cout</span><<<span class="hljs-string">"&#x804A;&#x5929;&#x5BA4;&#x4E2D;&#x4ECB;&#x8005;&#x6A21;&#x5F0F;&#x4EE3;&#x7801;"</span><<endl; chatroom * class="hljs-keyword">new ChatRoom();

    Participant *george=<span class="hljs-keyword">new</span> Beatle(<span class="hljs-string">"George"</span>);
    Participant *paul=<span class="hljs-keyword">new</span> Beatle(<span class="hljs-string">"Paul"</span>);
    Participant *ringo=<span class="hljs-keyword">new</span> Beatle(<span class="hljs-string">"Ringo"</span>);
    Participant *john=<span class="hljs-keyword">new</span> Beatle(<span class="hljs-string">"John"</span>);
    Participant *yoko=<span class="hljs-keyword">new</span> NonBeatle(<span class="hljs-string">"Yoko"</span>);

    chatRoom->registe(george);
    chatRoom->registe(paul);
    chatRoom->registe(ringo);
    chatRoom->registe(john);
    chatRoom->registe(yoko);

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

    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</endl;></participant></message<<endl;></name<<<span></from<<<span>

运行输出:

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

Original: https://www.cnblogs.com/gcczhongduan/p/6684561.html
Author: gcczhongduan
Title: 设计模式之二十一:中介者模式(Mediator)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/547287/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球