2010-06-01 49 views
1

這是我的飛行模擬應用程序。我現在正離開純粹的原型設計階段,現在開始充實軟件設計。至少我試試..使用多重繼承來區分使用角色?

模擬中的每架飛機都有與之相關的飛行計劃,其確切性質對此問題毫無興趣。足以說運營商在模擬運行時編輯飛行計劃。大多數時候飛機模型只需要讀取飛行計劃對象,這個對象起初被認爲只是傳遞一個const引用。但有些情況下,飛機需要撥打AdvanceActiveWayPoint()來表明已到達航點。這會影響函數ActiveWayPoint()返回的迭代器。這意味着飛機模型確實需要一個非常量參考,這反過來也會將諸如AppendWayPoint()之類的函數暴露給飛機模型。我想避免這種情況,因爲我想在編譯時強制執行上述使用規則。

請注意,class WayPointIter等同於STL常量迭代器,也就是說迭代器不能改變點的方式。

class FlightPlan 
{ 
public: 
    void AppendWayPoint(const WayPointIter& at, WayPoint new_wp); 
    void ReplaceWayPoint(const WayPointIter& ar, WayPoint new_wp); 
    void RemoveWayPoint(WayPointIter at); 

    (...) 

    WayPointIter First() const; 
    WayPointIter Last() const; 
    WayPointIter Active() const; 

    void AdvanceActiveWayPoint() const; 

    (...) 
}; 

我的想法來克服這個問題是這樣的:定義一個抽象接口類爲每個使用的作用,從兩個繼承航班計劃。然後,每個用戶只會獲得相應用戶角色的引用。

class IFlightPlanActiveWayPoint 
{ 
public: 
    WayPointIter Active() const =0; 
    void AdvanceActiveWayPoint() const =0; 
}; 

class IFlightPlanEditable 
{ 
public: 
    void AppendWayPoint(const WayPointIter& at, WayPoint new_wp); 
    void ReplaceWayPoint(const WayPointIter& ar, WayPoint new_wp); 
    void RemoveWayPoint(WayPointIter at); 

    (...) 

}; 

這樣的FlightPlan聲明只需要更改爲:

class FlightPlan : public IFlightPlanActiveWayPoint, IFlightPlanEditable 
{ 
    (...) 
}; 

你覺得呢?有沒有我可能錯過的窟窿?爲了清楚起見,這個設計是否清晰?還是我應該想出不同的想法?

或者我也可以定義一個特殊的ActiveWayPoint類,它將包含函數AdvanceActiveWayPoint(),但覺得這可能是不必要的。

提前致謝!

回答

1

從嚴格的設計角度來看,您的想法確實相當不錯。這相當於在這個對象上有一個單獨的對象和幾個不同的'視圖'。

但是這裏存在縮放問題(與實現有關)。如果你有另一個對象Foo需要訪問飛行計劃,你會添加IFlightPlanFoo接口?

有可能很快就會面臨繼承問題。

的傳統方法是創建另一個對象,Proxy,和使用該對象,以適應/限制/控制的使用。這是一個設計模式:Proxy

在這裏,您將創建:

class FlightPlanActiveWayPoint 
{ 
public: 
    FlightPlanActiveWayPoint(FlightPlan& fp); 

    // forwarding 
    void foo() { fp.foo(); } 

private: 
    FlightPlan& mFp; 
}; 

給它,你計劃IFlightPlanActiveWayPoint接口,具有實際FlightPlan對象的引用構建它,並轉發呼叫。

有幾個優點這種方法:

  • 相關性:這是不必要的編輯flightPlan.h每次有新的需求的時候,因此,不需要重建整個應用
  • 它的速度更快,因爲沒有虛再打電話,功能可以內聯(因此幾乎沒有)。雖然我會建議不要將它們內聯到一開始(所以你可以在不重新編譯所有內容的情況下修改它們)。
  • 可以很容易地添加檢查/記錄等,而無需修改基類(如果你有在特定情況下的一個問題)

我的2美分。

+0

謝謝!包括日誌記錄和額外檢查的可能性是我認爲非常有價值的補充。 – Arne 2010-06-01 09:45:45

0

不知道「窟窿」;-)但不是飛機的機組人員有時會在現實生活中自己修改飛行計劃嗎?例如。如果前方有暴風雨,或者目的地機場由於濃霧而無法使用。在危機情況下,飛機機長做出最終決定是有權的。當然,你可能決定不在你的模型中包括這個,但我認爲這是值得一提的。

多重繼承的替代方案可以是組合,使用Pimpl idiom的變體,其中包裝類不會公開內部類的完整接口。正如@Matthieu指出的那樣,這也被稱爲代理設計模式的變體。

+0

好吧,你是對的。在這種情況下,情況稍有不同。該模擬用於機場終端區域的空中交通。這個假設是,任何與預先計劃的飛行計劃的偏差都是空中交通管制員在地面上發出命令的結果。 – Arne 2010-06-01 09:23:10

+0

@阿德,我明白了,謝謝澄清。 – 2010-06-01 09:32:55