当一个对象改变某些值时要意识到

Realize when an object is changing some values

本文关键字:意识到 一个对象 改变      更新时间:2023-10-16

我使用c++和MFC(基于对话框)。

在我的主对话框中,我有一个对象称为内存(unsigned short*,模拟PLC内存)和另一个对象称为A类的test

对象test对内存有一个引用,并且能够改变它。在主对话框中有一些依赖于内存值的图形。

我的问题是:当对象test改变内存的任何值时,我如何更新这个图?

我可以给对象test一个对对话框的引用,每当test更改内存时,只需调用对话框方法来更新图形。这是不可能的,因为对象test(类A)不能有对对话框的引用(出于某种原因)。

另一个选择是设置一个计时器,每隔X毫秒重做一次图形,但这个选项对我来说似乎有点脏。

我认为对象测试可以在每次更改内存时发送消息PostMessage,但为了这样做,我需要对对话框的引用,对吗?

这里有一个Observer模式的完整工作示例。这是一个简单的例子,它并不打算是完美的,例如Observable类的name属性是一个设计问题。

我希望它能帮助你更好地了解Observer模式的工作原理。

#include <vector>
#include <iostream>
using namespace std;

class Observer
{
public:
    Observer(){};
    void notify(const char* name){
        cout << "Notyification from: " << name << endl;
    }
};

class Observable
{
public:
    Observable(const char* name):name(name){};
    // You can redefine in observable child classes the behaviour of notify_change.
    virtual void notify_change(){
        for (vector<Observer>::iterator it=observers.begin(); it != observers.end(); ++it)
        {
            (*it).notify(name);
        }
    }
    inline const char* get_name() {return name;}
    void register_observer(Observer obj){observers.push_back(obj);}
    // You should add something like unregister_observer too.
private:
    const char* name;
    vector<Observer> observers;
};

class Boss: public Observer {
public:
    Boss(){};
};
class Worker: public Observable {
public:
    Worker(const char* name):Observable(name){}
    void stop_working(){
        notify_change();
    }
};

int main()
{
    Boss some_boss;
    Worker some_worker("You");
    some_worker.register_observer(some_boss);
    some_worker.stop_working();
    return 0;
}

如果使用::PostMessage(hwndDialog,...),如果用对话框的hwnd初始化类A,则不需要对对话框的引用。这意味着类A不需要#include对话框类h文件

如果您可以修改测试类,一个可能的设计解决方案是使用模式"Observer"。通用的方法是让Test类继承IObservable接口,为观察者订阅和取消订阅提供API。同时让你的图形类和任何你想知道的类在内存中的变化,继承IObserver接口,提供API来通知对象一些重要的事件。

当观察对象发生重要变化时,例如改变了PLC内存,你可以使用IObserver API通知所有订阅的观察对象。

你可以让你的Observable类成为"Singletone",为它提供全局访问。你也可以使用任何合适的STL容器在observable(Test类)中存储观察者列表。

重要的是,在析构时不要忘记取消订阅观察者。除非你的可观察对象类可以尝试通知一些实际上已经不存在的对象。

如果你愿意,你可以直接在你的类中使用更简单的"观察者"方法,而不是使用接口。

您可以将内存封装在类M中,该类将接受IMemmoryChanged类型接口的订阅者。其中一个订阅者将是主对话框。接口可以有一个抽象函数OnChange()。您可以在主对话框中实现IMemmoryChanged接口。

当创建主对话框时,您可以创建M对象并调用M.AddSubscriber(dialog)

M::SetMemmory(unsigned short value)将更改私有内存对象,并通知其所有订阅者(其中一个订阅者是主对话框)。

所以当测试A调用M.SetMemmory时,主对话框将被通知

相关文章: