2010-06-01 25 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