如何封装属性集合

时间:2013-01-23 10:22:28

标签: c++ design-patterns architecture c++11

我正在开发人员疏散模拟器。首先,它将从XML文件加载树状建筑结构数据(楼层/房间/墙壁等),加载人员的初始配置,读取用户定义的移动模型参数并开始模拟。例如。对于每个模型步骤中的每个人,我需要找到他附近的所有几何对象,并选择最接近路径的路径 - 尽可能快地离开建筑物。

所以,我需要加载一个清晰的OOP方式来代表人们将移动的建筑物。 我坚持这个(只是例子):

class Aperture
{
   ...
public:
    virtual QRectF extent() = 0;
    virtual QString description() const = 0;
    // other common for all apertures methods

private:
   int m_srcRoomID;
   int m_dstRoomID;
   // other generic aperture properties
};

class Window: Aperture
{
    ...
public:
    virtual void extent() override;
    virtual QString description() override;
    // other overrides

private:
    EGlassType m_glassType;
    bool m_bOpenable;
    // other window-specific properties
};

// and other descendants: Door, CompositeDoor and so on

问题:我想将所有建筑物孔径存储在一个集合中作为抽象基础Aperture的指针,并且只使用基本虚拟函数而不需要任何转换为​​派生孔径。
但是:在疏散过程中,各种Aperture属性可能会发生变化,因此我需要以类型相关的方式修改它们。我无法使这个功能通用并将它放在基类:窗口没有更近,防火门不怕火 - 但其他人做,等等。可能有一种方法(例如设计模式)动态存储/添加/删除这些属性?或者完全避免继承子类化,因为构建项目的完整层次结构非常复杂和笨重。

2 个答案:

答案 0 :(得分:0)

您可以添加虚函数来设置基类Aperture中的属性,例如

virtual void update(vector)= 0;要么 virtual void update(...)= 0;

答案 1 :(得分:0)

嗯,决定关门的实体需要知道它可以关闭,甚至应该考虑改变这种状态。以下是一些选项:

  • 让对象以通用虚拟方法(类似Aperture::updateAperture::interactWithFireAperture::iteractWithPerson或类似方法)自行决定。
  • 使用Visitor pattern,即创建virtual Aperture::visit,它会在访问者上重新调用重载方法。这允许您仅为有意义的对象组合定义交互方法。
  • 使用“接口”,对可以关闭的任何内容IClosableDoor并在适当的位置IClosable * closable = dynamic_cast<IClosable *>(apperture); if(closable) { /* consider whether it should be closed */ }实际上你可能也会使用访问者模式的这种接口来减少必要的重载次数。

如果任何或其任何组合适合您,面向对象的方法是可行的。