• C++观察者模式


    * 观察者模式
    * [说明]
    *  在一公文处理系统中,开发者定义了一个公文类OfficeDoc, 其中定义了公文具有的属性和处理公文的相应方法。当公文件的内容或
    *状态发生变化时,关注此OfficeDoc 类对象的相应的DocExplorer 对象都要更新其自身的状态。一个OfficeDoc 对象能够关联一组
    *DocExplorer 对象。当OfficeDoc 对象的内容或状态发生变化时,所有与之相关联的DocExplorer对象都将得到通知,这种应用被称
    *为观察者模式。
    *
    * 例如MFC的DOC、VIEW架构都是基于这种观察者的模式。



    * 本代码还用了一种标示的方法实现了在运行时辨识对象。
    * RTTI只能在运行时实现类型的识别。没法实现对象的识别。

    #include <stdio.h>
    #include <typeinfo>

    // 最多与OfficeDoc关联的DocExplorer对象的个数
    const int OBS_MAX = 20;

    class COfficeDoc;

    // 关注OfficeDoc公文对象的类
    //##ModelId=44D02B1A01B9
    class CDocE

    asp.net 页面事件执行顺序

    xplorer
    {
    public:
    //##ModelId=44D02B1A01BA
    CDocExplorer(COfficeDoc *doc);
    //##ModelId=44D02B1A01BC
    void UpdateSelf(COfficeDoc *doc);

    // 为了实现对象的识别,在此加一个标示
    //##ModelId=44D02B1A01BE
    int nExplorerID;
    };

    //##ModelId=44D02B1A01D4
    class COfficeDoc
    {
    public:
    //##ModelId=44D02B1A01D5
    COfficeDoc()
    {
    index = 0;
    }

    //##ModelId=44D02B1A01D6
    void Attach(CDocExplorer *e)
    {
    if(index >= OBS_MAX || e == NULL)
    {
    return;
    }
    myObs[index] = e;
    index++;

    e->nExplorerID = index;
    }

    //##ModelId=44D02B1A01E4
    void Detach(CDocExplorer *e)
    {
    for(int i = 0; i <index; i++)
    {
    if(myObs[i] == e)
    {
    // 把当前位置的观察者对象和最后一个对象交换,并把indexhttp://www.sensiblefinds.com的值减一个
    if(i <= index-2)
    myObs[i] = myObs[index-1];
    myObs[index - 1] = NULL;
    index--;
    break;
    }
    }
    }

    // 修改数据,并通知观察者更新
    //##ModelId=44D02B1A01E6
    void ModifyData(int data)
    {
    printf("公文的数据改变成:%d/n", data);
    m_nData = data;
    NotifyObs();
    }

    private:
    //##ModelId=44D02B1A01E9
    CDocExplorer *myObs[OBS_MAX];// 观察者的类对象指针数组
    //##ModelId=44D02B1A01F4
    int index;

    // 通知所有的观察者对象改变自己的状态
    //##ModelId=44D02B1A01F5
    void NotifyObs()
    {
    for(int i = 0; i < index; i++)
    {
    myObs[i]->UpdateSelf(this);
    }
    }

    public:
    // 公文的数据
    //##ModelId=44D02B1A01F6
    int m_nData;
    };


    //##ModelId=44D02B1A01BA
    CDocExplorer::CDocExplorer(COfficeDoc *doc)
    {
    doc->Attach(this);
    }

    //##ModelId=44D02B1A01BC
    void CDocExplorer::UpdateSelf(COfficeDoc *doc)
    {
    // 把下面两行的注释打开还可以看到typeid和type_info的用法
    // 会发现typeid只能实现类型的识别

    //const type_info &t = typeid(*doc);
    //printf("我正在观察%s/n"http://www.pm300.com/, t.name());

    printf("我是观察者%d, ", nExplorerID);
    printf("更新数据: %d /n", doc->m_nData);
    }

    int main()
    {
    COfficeDoc officeDoc;
    CDocExplorer docExplorer0(&officeDoc);
    CDocExplorer docExplorer1(&officeDoc);
    CDocExplorer docExplorer2(&officeDoc);
    CDocExplorer docExplorer3(&officeDoc);
    CDocExplorer docExplorer4(&officeDoc);

    // 更新公文的数据
    officeDoc.ModifyData(123);
    printf("/n");
    officeDoc.ModifyData(567);

    return 0;
    }

  • 相关阅读:
    问题堆栈区39+40
    ListView优化分页优化
    AsyncTask理解- Day36or37
    Activity是如何挂载Pargment的Day35
    BroadcastReceiver和Intetnt的理解 Day34
    深入理解自定义ListView
    手势识别=读取手机联系人=ContentResolver-Day3
    Android本地JUnit Text
    Java——(一)一切都是对象
    SciTE: 中文字符支持问题
  • 原文地址:https://www.cnblogs.com/mfryf/p/2465030.html
Copyright © 2020-2023  润新知