观察者模式——向观察者传递信息

3

请原谅我的新手操作,以下是我需要完成的任务:

我有几个类(称之为A类),它们不断从各种来源(数据库、互联网等)收集信息。它们可能包含某个主题的大量信息。

我还有一堆类(称之为B类),如果提供足够的信息(这里,信息可以是一个或多个浮点值),它们可以渲染各种图形。

现在,我需要将这两个东西联系起来,以便我可以通过最小的更改修改显示的信息和形式。现在,我考虑在这里使用观察者模式,因为它似乎很适合这个问题。然而,我有点卡住了,希望能得到一些建议。我可以清楚地将A类定义为“数据源”基类型,允许订阅者并在更改时通知订阅者。我也可以将B类定义为“观察者”类型,并让它们订阅数据源并被通知更改。

问题是,我不想让我的观察者知道他们正在显示的任何特定类型的信息。例如,如果我想在Y轴上绘制城市温度,X轴上绘制时间,并且我有一个2D绘图类(类型为B),那么我希望避免任何A->GetTemperature()的调用。同样,在A类中,我不想调用NotifyOfTemperatureChange()或类似的东西...

一个想法是定义一堆枚举或字符串,例如“temperature”,“time”,“humidity”等,然后告诉观察者它应该监听什么(类似于A->SetYAxis(B,“temperature”)——在这里,我通知类A它应该从数据源B的渠道“temperature”获取单个浮点值作为其Y轴)

这样A就可以执行B->subscribeTo(我传递的内容)。这样,B就不需要知道它正在绘制的信息。A可以说notifyOfChangesOnThisChannel("temperature")。然而,对我来说,这似乎有点糊弄人...例如,数据是否实际传递到通知函数?我是否需要做这样的事情:

void B::subscriberChanged (int subscriberId, std::string channel)
{
    float value = datasource [subscriberId].GetCurrentValue (channel);
}

或者是类似于什么的东西?
void B::subscriberChanged (int subscriberId, std::string channel, void *data)
{
   float value = *static_cast <float *> (data);
}

此外,B 怎么知道数据类型呢?比如这个例子中是浮点数,但如果是整数或双精度数会怎样呢?

我的问题是:这样做正确吗?有没有更好的方法来解决这个问题?

提前感谢您的帮助。


1
你好!新手请见谅。下次,请将您的代码示例缩进四个空格以正确格式化它们。 - Björn Pollex
1个回答

3
您可以通过将观察者模式转换为模板类来解决此问题。然后,您需要定义一个最小接口(或概念),例如称为“Fact”,它将定义单个数据项的外观。您还可以定义一个名为“AxisDescription”的概念,它定义了如何描述轴(标签、单位、线性/对数等)。以下是一个简单的示例以说明:
template<class FactType, class AxisType>
class B {
public:
    b(AxisType axis); // initialization requires a description of the axis

    // called when a new fact is available
    void notify(FactType fact); 

    // called when many fact should be reported
    template<class FactIterator>
    void notify(FactIterator begin, FactIterator end); 
};
< p > FactType 可以是像floatint这样简单的类型,也可以更复杂,具体取决于您想要用它做什么。 < /p >

嗯..看起来这似乎是我没有考虑到的事情,这是一件好事。 :) 这种方式简化了问题。我想我会通过将FactType变成接口进行一些修改,这样我就可以得到诸如事实来源、类型和值之类的东西。这样我就可以把它匹配到应该显示它的地方。谢谢! - vmpstr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接