• 19 C++设计模式之中介者(Mediator)模式


    中介者(Mediator)模式定义

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

    中介者(Mediator)模式优缺点

    优点
    • 单一职责原则。你可以将多个组件间的交流抽取到同一位置,使其更易于理解和维护。
    • 开闭原则。你无需修改实际组件就能增加新的中介者。
    • 你可以减轻应用中多个组件间的耦合情况。
    • 你可以更方便地复用各个组件。
    缺点
    • 一段时间后,中介者可能会演化成为上帝对象

    中介者(Mediator)模式构成与实现

    构成
    • 组件(Component)是各种包含业务逻辑的类。每个组件都有一个指向中介者的引用,该引用被声明为中介者接口类型。组件不知道中介者实际所属的类,因此你可通过将其连接到不同的中介者以使其能在其他程序中复用。
    • 中介者(Mediator)接口声明了与组件交流的方法, 但通常仅包括一个通知方法。组件可将任意上下文(包括自己的对象)作为该方法的参数,只有这样接收组件和发送者类之间才不会耦合。
    • 具体中介者(Concrete Mediator)封装了多种组件间的关系。具体中介者通常会保存所有组件的引用并对其进行管理,甚至有时会对其生命周期进行管理。
    • 组件并不知道其他组件的情况。如果组件内发生了重要事件,它只能通知中介者。中介者收到通知后能轻易地确定发送者,这或许已足以判断接下来需要触发的组件了。对于组件来说,中介者看上去完全就是一个黑箱。发送者不知道最终会由谁来处理自己的请求,接收者也不知道最初是谁发出了请求。
    实例

    Mediator.h:

    #ifndef MEDIATOR_H_
    #define MEDIATOR_H_
    
    #include 
    
    class Colleague;
    
    // 抽象中介者
    class Mediator {
     public:
        // 声明抽象方法
        virtual void registerMethod(Colleague*) = 0;
        // 声明抽象方法
        virtual void operation(Colleague*) = 0;
    };
    
    #endif  // MEDIATOR_H_
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    Component.h:

    #ifndef COMPONENT_H_
    #define COMPONENT_H_
    
    #include "Mediator.h"
    #include 
    #include 
    
    enum PERSON_TYPE {
        kUnknown,
        kLandlord,
        kTenant,
    };
    
    // 组件基类
    class Colleague {
     public:
        void set_mediator(Mediator *m) {
            mediator_ = m;
        }
        Mediator* get_mediator() {
            return mediator_;
        }
        void set_personType(PERSON_TYPE pt) {
            person_type_ = pt;
        }
        PERSON_TYPE get_person_type() {
            return person_type_;
        }
        virtual void ask() = 0;
        virtual void answer() = 0;
     private:
        Mediator* mediator_;
        PERSON_TYPE person_type_;
    };
    
    // 具体组件1: 房东
    class Landlord : public Colleague {
     public:
        Landlord() {
            name_ = "unknown";
            price_ = -1;
            address_ = "unknown";
            phone_number_ = "unknown";
            set_personType(kUnknown);
        }
    
        Landlord(std::string name, int price, std::string address, std::string phone_number) {
            name_ = name;
            price_ = price;
            address_ = address;
            phone_number_ = phone_number;
            set_personType(kLandlord);
        }
    
        void answer() override {
            printf("房东姓名:%s 房租:%d 地址:%s 电话:%s\n", name_.c_str(), price_, address_.c_str(), phone_number_.c_str());
        }
    
        void ask() override {
            printf("房东%s查看租客信息: \n", name_.c_str());
            this->get_mediator()->operation(this);
        }
    
     private:
        std::string name_;
        int price_;
        std::string address_;
        std::string phone_number_;
    };
    
    // 具体组件2: 租客
    class Tenant : public Colleague {
     public:
        Tenant() {
            name_ = "unknown";
        }
        explicit Tenant(std::string name) {
            name_ = name;
            set_personType(kTenant);
        }
        void ask() {
            printf("租客%s询问房东信息:\n", name_.c_str());
            this->get_mediator()->operation(this);
        }
        void answer() {
            printf("租客姓名: %s\n", name_.c_str());
        }
    
     private:
        std::string name_;
    };
    
    #endif  // COMPONENT_H_
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93

    ConcreteMediator.h:

    #ifndef CONCRETE_MEDIATOR_H_
    #define CONCRETE_MEDIATOR_H_
    
    #include 
    #include 
    #include "Component.h"
    #include "Mediator.h"
    
    // 具体中介类: 房产中介
    class Agency : public Mediator {
     public:
        void registerMethod(Colleague* person) override {
            switch (person->get_person_type()) {
                case kLandlord:
                    landlord_list_.push_back(reinterpret_cast<Landlord*>(person));
                    break;
                case kTenant:
                    tenant_list_.push_back(reinterpret_cast<Tenant*>(person));
                    break;
                default:
                    printf("wrong person\n");
            }
        }
    
        void operation(Colleague* person) {
            switch (person->get_person_type()) {
                case kLandlord:
                    for (int i = 0; i < tenant_list_.size(); i++) {
                        tenant_list_[i]->answer();
                    }
                    break;
                case kTenant:
                    for (int i = 0; i < landlord_list_.size(); i++) {
                        landlord_list_[i]->answer();
                    }
                    break;
                default:
                    break;
            }
        }
    
     private:
        std::vector<Landlord*> landlord_list_;
        std::vector<Tenant*> tenant_list_;
    };
    
    #endif  // CONCRETE_MEDIATOR_H_
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    main.cpp

    #include 
    #include "ConcreteMediator.h"
    #include "Component.h"
    
    int main() {
    
        system("chcp 65001");
        // 房产中介
        Agency *mediator = new Agency();
    
        // 三位房东
        Landlord *l1 = new Landlord("张三", 1820, "天津", "1333");
        Landlord *l2 = new Landlord("李四", 2311, "北京", "1555");
        Landlord *l3 = new Landlord("王五", 3422, "河北", "1777");
        l1->set_mediator(mediator);
        l2->set_mediator(mediator);
        l3->set_mediator(mediator);
        mediator->registerMethod(l1);
        mediator->registerMethod(l2);
        mediator->registerMethod(l3);
    
        // 两位租客
        Tenant *t1 = new Tenant("Zhang");
        Tenant *t2 = new Tenant("Yang");
        t1->set_mediator(mediator);
        t2->set_mediator(mediator);
        mediator->registerMethod(t1);
        mediator->registerMethod(t2);
    
        // 业务逻辑
        t1->ask();
        std::cout << std::endl;
        l1->ask();
    
        system("pause");
        delete mediator;
        delete l1;
        delete l2;
        delete l3;
        delete t1;
        delete t2;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    输出:

    Active code page: 65001
    租客Zhang询问房东信息:
    房东姓名:张三 房租:1820 地址:天津 电话:1333
    房东姓名:李四 房租:2311 地址:北京 电话:1555
    房东姓名:王五 房租:3422 地址:河北 电话:1777
    
    房东张三查看租客信息:
    租客姓名: Zhang
    租客姓名: Yang
    Press any key to continue . . .
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
  • 相关阅读:
    站长告诉怎么选择网站服务器
    11.数组的分类和定义
    一个漏测Bug能让你想到多少?
    (黑客)网络安全———自学方法
    前馈型BP神经网络
    素食者进行低碳饮食的最佳方法
    golang基于errgroup实现并发调用
    yolov5剪枝实战3: yolov5-slimming项目运行演示
    java开发手册-06工程结构
    【CKA考试笔记】十八、StatefulSet
  • 原文地址:https://blog.csdn.net/qq_45531502/article/details/126419441