[12 使用C++11开发一个对象的消息总线(观察者模式和中介者模式的应用及优化)] 12.4 应用实例

假设有3个对象Car,Bus,Truck,都向消息总线注册了消息,消息类型为std::function<void(int)>,其中Car,Bus在注册时指定了主题。这三个对象在注册完消息后,希望能收到感兴趣的消息并处理,并不关心是谁给他们发送消息;另外,有个Subject会发送消息,Subject并不关心实惠收到消息。

3个对象和Subject对象没有耦合关系,它们之间唯一的联系就是消息总线。MessageBus的一个应用示例如下:

#include "MessageBus.hpp"

MessageBus g_bus;
const string Topic = "Drive";
struct Subject
{
    void SendReq(const string& topic)
    {
        g_bus.SendReq<void, int>(500,topic);
    }
};

Struct Car
{
    Car()
    {
        g_bus.Attach([this](int speed){ Drive(speed); }, Topic);
    }

    void Drive(int speed)
    {
        cout << "Car drive " << speed << endl;
    }
};

Struct Bus
{
    Bus()
    {
        g_bus.Attach([this](int speed){ Drive(speed); }, Topic);
    }

    void Drive(int speed)
    {
        cout << "Bus drive " << speed << endl;
    }
};

Struct Truck
{
    Truck()
    {
        g_bus.Attach([this](int speed){ Drive(speed); });
    }

    void Drive(int speed)
    {
        cout << "Truck drive " << speed << endl;
    }
};

void TestBus()
{
    Subject subject;
    Car car;
    Bus bus;
    Truck truck;

    subject.SendReq(Topic);
    cout << "-------" << endl;
    subject.SendReq("");

    g_bus.Remove<void, int>();
    subject.SendReq("");
}

输出结果如下:
Car drive
Bus drive
-------
Truck drive

subject发送"Drive"主题的消息时,Car和Bus接收消息并处理;subject发送""消息时,Truck接收消息并处理。消息总线删除std::funciton<void(int)>消息后,接收者不再接收消息。

需求变复杂:在3个对象接收并处理完消息后,需要再告诉发送者消息已经处理完成。

MessageBus的应用示例如下:

#include "MessageBus.hpp"

MessageBus g_bus;
const string Topic = "Drive";
const string CallBackTopic = "DriveOk";
struct Subject
{
    Subject 
    {
        // 主题也注册消息
        g_bus.Attach([this]{ DriveOk(); }, CallBackTopic);
    }

    void SendReq(const string& topic)
    {
        g_bus.SendReq<void, int>(500,topic);
    }

    void DriveOK()
    {
        cout << "drive ok" << endl;
    }
};


Struct Car
{
    Car()
    {
        g_bus.Attach([this](int speed){ Drive(speed); }, Topic);
    }

    void Drive(int speed)
    {
        cout << "Car drive " << speed << endl;
        // 接收者处理消息后,回复消息给发送者
        g_bus.SendReq<void>(CallBackTopic);
    }
};

Struct Bus
{
    Bus()
    {
        g_bus.Attach([this](int speed){ Drive(speed); }, Topic);
    }

    void Drive(int speed)
    {
        cout << "Bus drive " << speed << endl;
        // 接收者处理消息后,回复消息给发送者
        g_bus.SendReq<void>(CallBackTopic);
    }
};

Struct Truck
{
    Truck()
    {
        g_bus.Attach([this](int speed){ Drive(speed); });
    }

    void Drive(int speed)
    {
        cout << "Truck drive " << speed << endl;
        // 接收者处理消息后,回复消息给发送者
        g_bus.SendReq<void>(CallBackTopic);
    }
};

void TestBus()
{
    Subject subject;
    Car car;
    Bus bus;
    Truck truck;

    subject.SendReq(Topic);
    cout << "-------" << endl;
    subject.SendReq("");

    g_bus.Remove<void, int>();
    subject.SendReq("");
}

输出结果如下:
Car drive
drive ok
Bus drive
drive ok
-------
Truck drive
drive ok

可以看到用户只需维护主题与消息,对象(Car,Bus,Truck)之间都是松耦合。

注意:

消息总线的使用场景适用于对象很多且关系复杂的时候,对于对象较少且关系简单的不要使用消息总结使得简单问题复杂化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值