我想讓人們對以下方法有所瞭解,甚至建議更好的替代方案。默認爲屬性的訪問者模式
我有一個天氣模擬,我希望能夠隨着模擬的進展計算出特定的屬性。假設我有一個基類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
。我在我的WeatherSim
中存儲了一個Visitors
的矢量,每次迭代我都會調用Visitors
來完成它們的工作。每位訪客將接受對WeatherSim
的引用,因此他們可以在內部存儲他們的運行平均值。
在我看來,這是一個解決這個問題的好方法,除了還有兩件事我需要解決,這就是爲什麼我在這裏。
某些屬性需要在特定的模擬中執行計算。因此,例如,我可能需要在我的
ConstantTempWeatherSim
中使用壓力作爲算法的一部分。我是否應該將所需財產的移動平均值與我的Visitors
分開保存,並使用它們來增加WeatherSim
已計算的財產?或者我應該有一個私人矢量PropertyVisitors
,我使用了必要的屬性,並讓用戶將其他所需的任何東西添加到單獨的隊列中?有沒有其他的方法?每次迭代後,
WeatherSim
都會呼叫觀察者記錄所需的信息。將數據從PropertyVisitors
轉換爲Observer
的最佳方法是什麼?我不認爲將向PropertyVisitors
本身的引用向量傳遞給Observers
是明智的。我在考慮在我的SimEvent
類中包含有關事件的信息,我可以從所有PropertyVisitors
中獲取值,並將它們存儲在SimEvent
的矢量中。還是我吠叫錯了樹?
也許訪客模式不是最好的方法。我將不勝感激關於如何解決這個問題的想法。
謝謝大家提前!
我不清楚'模型'是什麼?或'WeatherSim'如何與「屬性」相關。我認爲[MCVE](http://stackoverflow.com/help/mcve)會有所幫助。當然,任何MCVE都會大大簡化事情,但我認爲這至少有助於理解你提到的不同對象的角色以及它們之間的相互關係。 – 2015-03-14 13:41:34
您的示例似乎表明「特性」是作爲「WeatherSim」爲特定迭代完成的計算的結果而計算的。但WeatherSim也可能使用一些屬性作爲計算的一部分。那是使用來自以前迭代的屬性嗎?或者是否存在某種依賴關係圖,在計算壓力屬性之前,您無法計算其他內容。 – 2015-03-14 13:56:29
對不起,沒有清晰度。模型僅僅是一個體積的表示,比如說大西洋中部的一個30立方英里的區域。 「WeatherSim」在該捲上運行。所以屬性的思想非常簡單 - 沒有依賴關係圖,所有屬性都只是表示「模型」的特定狀態。例如,如果我想要一個'ConstantTemperature' Sim,那麼它會監測每次迭代的溫度並調整盒子的體積(保持該溫度)。 – pragmatist1 2015-03-14 15:12:59