我想找人们#39;关于以下方法的想法,甚至可能提出更好的替代方案。
我有一个天气模拟,我希望能够在模拟过程中计算出特定的属性。假设我有一个基类WeatherSim
,从中可以得到不同类型的模拟。所以我可能有ConstantTemperatureWeatherSim
或ConstantPressureWeatherSim
等等。
在ConstantTemperatureWeatherSim
的情况下,我可能对平均气压如何随时间变化(实际模拟中的迭代)等感兴趣,等等。我也可以运行相同的模拟,我想监视其他属性,例如平均速度场矢量,或者我想要的任意数量。
问题是,我需要以最有效的方式计算属性,因为这些模拟非常计算成本高。这意味着虽然我可以有一个属性计算函数的向量,如下所示:
class ConstTempWeatherSim {
std::vector<std::function<double(Model&)>> properties;
void Iterate() {
// Perform calculations...
// Calculate properties
for(auto& property : properties)
property(model);
}
这种方法效率很低。对于平均压力的情况,我可以循环模型中的所有元素,并在每次迭代时获得压力属性。更有效的方法是保持平均运行。
问题是,我不想以尽可能可计算的数量污染我的班级(坦率地说,即使我想要,我也不能,因为我不知道什么是奇怪的财产用户可能想要计算)。
我对此问题的解决方案是使用某种访问者模式。我的WeatherSim
是Visitable
对象,我要计算的属性是Visitor
。我在Visitors
中存储了WeatherSim
的向量,每次迭代我都会调用Visitors
来做他们的事情。每位访问者都会接受WeatherSim
的引用,因此他们可以在内部存储其平均值。
在我看来,这是解决这个问题的好方法,除了我需要解决的其他两件事,这就是我在这里的原因。
在特定模拟中执行计算需要一些属性。因此,例如,我可能需要在ConstantTempWeatherSim
中使用压力作为算法的一部分。我应该将所需属性的运行平均值与Visitors
分开保存,并使用它们来扩充WeatherSim
已经计算过的属性吗?或者我应该有一个PropertyVisitors
的私有向量,我用于必要的属性,并让用户将他们需要的任何东西添加到一个单独的队列?还有其他方式吗?
每次迭代后,WeatherSim
会调用Observers来记录所需的信息。从PropertyVisitors
到Observer
获取数据的最佳方法是什么?我不认为将PropertyVisitors
本身的引用向量传递给Observers
是明智的。我想在我的SimEvent
课程中,其中包含有关该事件的信息,我可以从所有PropertyVisitors
获取值,并将它们存储在SimEvent
中的向量中。还是我在错误的树上吠叫?
也许访客模式不是最佳方法。我很感激如何解决这个问题。
提前谢谢大家!
答案 0 :(得分:0)
访客模式在这里感觉有点奇怪。通常使用访客模式,访问者需要了解所有不同的可访问类型。这就是它如何实现对访客类型和可访问类型的双重调度。如果不同的可访问类型相当静态,但您可能需要在将来添加新访问者,这是合适的。在你的情况下,这意味着属性需要知道所有不同类型的WeatherSim
,这对我来说听起来不太合适。我不会期待那种耦合。
但是基于我有限的理解来回答你的具体问题:
Pressure
属性需要符合要注册的某些“压力”接口/模板。SimEvent
中。或者你只是告诉观察者一些事情发生了变化,观察者有责任从模拟中提取他们需要的信息。我认为两者都是有效的运行方式,哪种方式将取决于您的特定要求。推送模型可能效率低下,因为即使某个特定观察者可能对某些数据不感兴趣,您也必须推送所有数据。拉模型效率低,因为通信分两步完成,观察者可能必须找出自己确切改变了哪些数据。拉模型在观察者和模拟之间引入了更多的耦合。在推送模型中,您可能必须更改每次Observer需要新内容时推送的数据集。