• 监听者观察者模式


         在C++模式设计中,常用的一种模式设计方法就是监听者-观察者模式。每个监听者对象都把自己理解的事件注册到一个中心事件处理注册库,接收到消息后,中心事件处理注册库会把该消息分发到每个监听者对象。

        下面是来自于c++ profressional中的代码:

    首先是监听者类:

    Listener.h 和Listener.cpp,这是一个监听者基类,该类中定义了消息处理的纯虚函数,代码如下:

    #pragma once

    class Listener
    {
    public:
    Listener(void);
    ~Listener(void);
    virtual void handleMessage(int inMessage) = 0;
    };
    #include "Listener.h"

    Listener::Listener(void)
    {
    }

    Listener::~Listener(void)
    {
    }

    派生的监听类是TestListener, 该类实现如下:

    TestListener.h

    #pragma once
    #include "listener.h"
    #include "EventRegistry.h"

    class TestListener :
    public Listener
    {
    public:
    TestListener(void);
    ~TestListener(void);

    void handleMessage(int inMessage);
    bool fMessage0Received;
    bool fUnknownMessageReceived;
    };

    TestListener.cpp,该类在构造函数中,把自己及消息0注册到中心事件处理库

    #include "TestListener.h"

    TestListener::TestListener(void)
    {
    fMessage0Received = false;
    fUnknownMessageReceived = false;
    //订阅事件0
    EventRegistry::registerListener(0, this);
    }

    TestListener::~TestListener(void)
    {
    }

    void TestListener::handleMessage(int inMessage)
    {
    switch (inMessage)
    {
    case 0:
    fMessage0Received = true;
    break;
    default:
    fUnknownMessageReceived = true;
    break;
    }
    }

    下面是事件注册类的实现,在该类中每增加一个监听者类,都会把该类的引用增加到一个map中,该类的实现代码如下:

    EventRegistry.h和EventRegistry.cpp

    #pragma once
    #include <vector>
    #include <map>
    #include <iostream>
    #include "Listener.h"
    using namespace std;

    class EventRegistry
    {
    public:
    EventRegistry(void);
    ~EventRegistry(void);
    static void registerListener(int inMessage, Listener* inListener);
    static void handleMessage(int inMessage);
    protected:
    static map<int, vector< Listener*> > sListenerMap;
    };
    #include "EventRegistry.h"

    //定义静态map
    map<int, vector< Listener*> > EventRegistry::sListenerMap;
    EventRegistry::EventRegistry(void)
    {
    }

    EventRegistry::~EventRegistry(void)
    {
    }

    void EventRegistry::registerListener(int inMessage, Listener* inListener)
    {
    //注册监听器
    sListenerMap[inMessage].push_back(inListener);
    }
    void EventRegistry::handleMessage(int inMessage)
    {
    // 查找指定消息,然后处理所有注册该消息的监听类
    if (sListenerMap.find(inMessage) == sListenerMap.end()) return;
    for (int i = 0; i < sListenerMap[inMessage].size(); i++) {
    sListenerMap[inMessage].at(i)->handleMessage(inMessage);
    }
    }

    在main函数中,中心注册类接收到了消息0,1,2,然后分发注册的监听类,TestListener注册了消息0,可以通过fMessage0Received变量验证,它确实收到了消息0。

    #include <stdio.h>
    #include <stdlib.h>
    #include <iostream>
    #include "EventRegistry.h"
    #include "Listener.h"
    #include "TestListener.h"

    using namespace std;

    int main(int argc, char* argv[])
    {

    TestListener tt ;
    EventRegistry::handleMessage(0);
    EventRegistry::handleMessage(1);
    EventRegistry::handleMessage(2);
    if (!tt.fMessage0Received) {
    cout << "TEST FAILED: Message 0 was not received" << endl;
    } else if (tt.fUnknownMessageReceived) {
    cout << "TEST FAILED: TestListener received unknown message" << endl;
    } else {
    cout << "TEST PASSED" << endl;
    }

    return 0;
    }

    源码下载:

    https://files.cnblogs.com/mikewolf2002/WatchListener.zip

  • 相关阅读:
    RecyclerView 下拉刷新上拉加载
    Android 添加、移除和判断 桌面快捷方式图标
    似曾相识的 RecyclerView
    http 需要掌握的知识点(一)
    android 数据存储操作之SQLite
    Android 图片加载[常见开源项目汇总]
    Android 命名规范和编码规范
    线程池及增长策略和拒绝策略
    静态代理和动态代理的区别
    FastJson学习
  • 原文地址:https://www.cnblogs.com/mikewolf2002/p/2728279.html
Copyright © 2020-2023  润新知