【设计模式】中介者模式分析及源码

用一个中介者对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使耦合松散,而且可以独立地改变它们之间的交互。

在这里插入图片描述
中介者模式又称为调停者模式,从类图中看,共分为3部分:

  • 抽象中介者:定义好同事类对象到中介者对象的接口,用于各个同事类之间的通信。一般包括一个或几个抽象的事件方法,并由子类去实现。
  • 中介者实现类:从抽象中介者继承而来,实现抽象中介者中定义的事件方法。从一个同事类接收消息,然后通过消息影响其他同时类。
  • 同事类:如果一个对象会影响其他的对象,同时也会被其他对象影响,那么这两个对象称为同事类。在类图中,同事类只有一个,这其实是现实的省略,在实际应用中,同事类一般由多个组成,他们之间相互影响,相互依赖。同事类越多,关系越复杂。并且,同事类也可以表现为继承了同一个抽象类的一组实现组成。在中介者模式中,同事类之间必须通过中介者才能进行消息传递。
为什么要使用中介者模式

一般来说,同事类之间的关系是比较复杂的,多个同事类之间互相关联时,他们之间的关系会呈现为复杂的网状结构,这是一种过度耦合的架构,即不利于类的复用,也不稳定。例如在下图中,有六个同事类对象,假如对象1发生变化,那么将会有4个对象受到影响。如果对象2发生变化,那么将会有5个对象受到影响。也就是说,同事类之间直接关联的设计是不好的。

在这里插入图片描述

如果引入中介者模式,那么同事类之间的关系将变为星型结构,从图中可以看到,任何一个类的变动,只会影响的类本身,以及中介者,这样就减小了系统的耦合。一个好的设计,必定不会把所有的对象关系处理逻辑封装在本类中,而是使用一个专门的类来管理那些不属于自己的行为。
在这里插入图片描述

源码
#include <iostream>
#include <string>
#include <unordered_map>

namespace mediator_pattern {
class abstract_mediator;

class abstract_colleague
{
public:
    virtual void send_message(int, std::string) = 0;
    virtual void receive_message(std::string) = 0;
    virtual void set_mediator(abstract_mediator* mediator) {
        mediator_ = mediator;
    }
protected:
    abstract_mediator *mediator_;
}; // class abstract_colleague

class abstract_mediator {
public:
    virtual void operation(int, std::string) = 0;
    virtual void register_colleague(int, class abstract_colleague
*) = 0;
};// class abstract_mediator

class concrete_colleague_1 : public abstract_colleague{
public:
    void send_message(int id, std::string message) override {
        std::cout << "concrete_colleague_1 will send message: [" << message << "] to " << std::to_string(id) << std::endl;
        mediator_->operation(id, message);
    }
    void receive_message(std::string message) override {
        std::cout << "concrete_colleague_1 => receive_message : [" << message << "]" << std::endl;
    }
}; // class concrete_colleague_1

class concrete_colleague_2 : public abstract_colleague{
public:
    void send_message(int id, std::string message) override {
        std::cout << "concrete_colleague_2 will send message: [" << message << "] to " << std::to_string(id) << std::endl;
        mediator_->operation(id, message);
    }
    void receive_message(std::string message) override {
        std::cout << "concrete_colleague_2 => receive_message : [" << message << "]" << std::endl;
    }
}; // class concrete_colleague_2

class concrete_mediator : public abstract_mediator {
public:
    void operation(int id, std::string message) override {
        std::cout << "concrete_mediator - operation => will send message: [" << message << "] to " << std::to_string(id) << std::endl;
        lists_[id]->receive_message(message);
    }
    void register_colleague(int id, abstract_colleague* colleague) override {
        lists_[id] = colleague;
        colleague->set_mediator(this);
    }
private:
    std::unordered_map<int, abstract_colleague *> lists_;
}; // class concrete_mediator
}// namespace mediator_pattern

int main() {
    mediator_pattern::concrete_mediator _concrete_mediator;
    mediator_pattern::concrete_colleague_1 _concrete_colleague_1;
    mediator_pattern::concrete_colleague_2 _concrete_colleague_2;
    _concrete_mediator.register_colleague(1, &_concrete_colleague_1);
    _concrete_mediator.register_colleague(2, &_concrete_colleague_2);

    _concrete_colleague_1.send_message(2, "message from _concrete_colleague_1 to _concrete_colleague_2");
    std::cout << std::endl;
    _concrete_colleague_2.send_message(1, "message from _concrete_colleague_2 to _concrete_colleague_1");
    return 0;
}

输出结果为:

concrete_colleague_1 will send message: [message from _concrete_colleague_1 to _concrete_colleague_2] to 2
concrete_mediator - operation => will send message: [message from _concrete_colleague_1 to _concrete_colleague_2] to 2
concrete_colleague_2 => receive_message : [message from _concrete_colleague_1 to _concrete_colleague_2]

concrete_colleague_2 will send message: [message from _concrete_colleague_2 to _concrete_colleague_1] to 1
concrete_mediator - operation => will send message: [message from _concrete_colleague_2 to _concrete_colleague_1] to 1
concrete_colleague_1 => receive_message : [message from _concrete_colleague_2 to _concrete_colleague_1]
总结

有点晕,向中介者提交请求时需要信息。

至于是谁处理信息,可能有两种:

  1. 中介者自定义
  2. 发送请求的人规定

是这样吗??

如果某一个请求属于某一特定行为,则指定特定接收者??

发布了349 篇原创文章 · 获赞 14 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/LU_ZHAO/article/details/105305199