2011-01-19 194 views
3

请原谅任何和所有newbieness),观察者模式 - 将信息传递给观察者

我有以下的任务来执行:

我有几个类(称这些A)是不断地从收集信息各种来源(数据库,互联网等)。他们可以包含有关某些主题的潜在的大量信息。我还有一堆类(称为这些B),允许我呈现各种图表(如果提供了足够的信息)(这里的信息可以如同一个或多个浮点值一样简单)。

现在,我要这两件事情联系在一起,这样我可以修改的信息显示在其形成与最小的变化。现在,我正在考虑在这里使用观察者模式,因为它似乎很好地解决了这个问题。但是,我有点卡住,并希望建议。我可以明确地创建“数据源”基类型的类A,它允许订阅者并在发生更改时通知订阅者。我也可以制作类型为“观察者”的B类,并让他们订阅数据源并收到变更通知。

的问题是,我不希望我的观察员知道他们正在显示的信息的任何特定类型。举例来说,如果我想绘制温度在我的Y轴和时间上的X轴城市,我有一个2D-情节类(B类),那么我想避免任何形式的A->GetTemperature()电话。同样,在A级,我不想叫NotifyOfTemperatureChange()或类似的东西...

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

这样A就可以做B->subscribeTo (whateverIPassedIn)。这样,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知道数据的类型?我的意思是在这个例子中它是一个浮点数,但如果它是一个int或一个double呢?

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

谢谢你提前

+1

嗨!新手请原谅。下一次,将您的代码示例缩进四个空格,以使其格式正确。 – 2011-01-19 14:57:48

+0

会做。谢谢。 – vmpstr 2011-01-19 15:43:18

回答

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); 
}; 

FactType可以像floatint一样简单,但也更复杂,这取决于你想用它做什么。