2013-10-15 22 views
0

DisplayEngine有一個DisplayableObjects列表。每個DisplayableObject派生類都使用一組不同的數據。所以我爲數據創建了一個基類,以便我可以將BaseData傳遞到每個DisplayableObject的更新中,而無需知道有關DisplayableObject和BaseData派生類的任何信息。然後在每個派生的DisplayableObject更新函數中,我投射到正確類型的數據。如何避免語義耦合來創建可重用的顯示引擎?

問題是這是一個語義耦合。如果我將錯誤的派生數據類傳遞給派生的DisplayableObject類之一,那麼這種情況就會發生,而且真正的更新函數確實無法處理所有BaseData類,就像它看起來在外面一樣。

基本上這裏發生的是Module1將BaseObject傳遞給Module2。由於Module2知道Module2確實將其傳遞給DerivedObject,因此它會將BaseObject轉換爲DerivedObject並使用特定於DerivedObject的數據。

問題是,我找不出一種方法來做到這一點。我如何獲得Displayable對象列表,每個Displayable對象都採用不同的數據集,並讓DisplayEngine對任何派生類都一無所知,以便我可以在另一個項目中重用DisplayEngine?

這有點複雜,所以提前感謝您看看它。

Class DisplayEngine{ 
    DisplayableObject displayableObjectsList[10]; 
    BaseData *dataList[10]; 
    // Each element in data list is updated somewhere else. 

    void UpdateAll(){ 
     for(int i=0; i<10; i++){ 
      displayableObjectsList[i].Update(dataList[i]); 
     } 
    } 
} 

Class DisplayableObject{ 
    virtual void Update(BaseData bData); 
} 

Class BaseData { 
    //empty. 
} 

Class Data1 : BaseData{ 
    String b; 
} 

Class Data2: BaseData{ 
    int a;  
} 

Class DisplayableObject1: DisplayableObject{ 
    void Update(BaseData bData){ 
     Data1* d = (Data1*) bData; 
     //Do Work with d, can use d.b 
    } 
} 

Class DisplayableObject2: DisplayableObject{ 
    void Update(BaseData bData){ 
     Data2* d = (Data2*) bData; 
     //Do Work with d, can use d.a 
    } 
} 

回答

0

嘗試使用訪問者模式。 你可以閱讀所有關於它的信息here

如果你有更多的問題或者你需要額外的例子,隨時問。

+0

謝謝你的迴應。我之前沒有聽說過訪問者模式,這很有趣,雖然我不確定它會在這裏工作。在這種模式下,訪問者需要爲每種元素類型實現一種方法。就我而言,我的displayableObjects列表不需要對每個baseData派生類型做不同的事情,它只處理其中的一個。每個displayableObject都將顯示來自一個baseData派生數據類的數據。但是,我可以在這裏使用解決方案中的訪問者模式中的一些概念,我將不得不花費更多的時間。再次感謝! – Ganamede

+0

只需在基礎中實現一個空實現並覆蓋一個方法即可處理您的特定數據類型。 – RonenKr

+0

對,可以工作!我可以預見的唯一問題是在大型項目中,如果有大量可顯示對象並因此有數據類,那麼每次添加新對象時都必須修改每個對象。這會使添加新的顯示對象非常耗時。建議? – Ganamede