c++ - Liskov 替换原则和游戏的类设计

标签 c++ oop solid-principles

在我的游戏中我定义了一个 Screen类,其中包含对多个视觉对象的引用 Entity可能被绘制到显示器上的对象:

class Screen {
public:

private:
  std::vector<Entity*> entities_;
};

全部Entity的,有一个 Draw()功能:

class Entity {
  public:
    void Draw();
  private:
    int xpos;
    int ypos;
};

Screen负责调用 Draw()在其每个 Entity 上运行

问题是一些(但不是全部)Entity的也需要是可更新的,即随着时间的推移,它们会改变它们的外观/位置。 Screen还需要调用 Update()函数但仅适用于那些可更新的对象

我的问题是:

Entity派生一个类有意义吗?具有更新功能:

class ChangingEntity : public Entity {
  public: 
     void Update(int time);
};

并且有Screen看起来像这样:

class Screen {
public:

private:
  std::vector<Entity*> entities_;
  std::vector<ChangingEntity*> changing_entities_;
};

如果我执行上述操作,那么我只会调用 Draw()对于每个 Entity s 和 Draw()Update()在每个 ChangingEntity

或者 - 我应该把 Update()Entity 中发挥作用, 如果 Entity对象无法更新,则 Update()没有实现?

最佳答案

您可以在此处增强一些功能;

最好不要让实体自己绘制,使用单独的 Draw() 函数或 Drawable 类 ( Single Responsibility Principle )。在您当前的方法中,您正在创建任何需要绘制以扩展实体的类,下次您会发现一个类不需要是可绘制的实体。所以使用单独的绘制函数。

其次你应该定义实体是什么,例如 Ogre3D 定义 Entity作为基于网格的离散、可移动对象的实例,我认为您当前的定义不够充分,它仅包含位置和绘制函数。您可以将一个实体定义为一个 Updatable 对象,而另一个名为 StaticEntity 的类则不需要多态性。让场景有两个单独的列表,实际上能够更新对象,再次将渲染器与场景分开。

第三,你的 Screen 类应该被称为 Renderer 并且有可以渲染的对象根据它们的静态类型注册。你也可以有一个 Drawable 接口(interface)。

关于c++ - Liskov 替换原则和游戏的类设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22037079/

相关文章:

c++ - 项目中缺少 guiddef.h

c++ - 在多个查询的子数组中查找不同(唯一)值的数量

java - 当一个类被另外两个类扩展时获取空值

c# - 是否可以在同一个类中覆盖一个函数?

c# - 固体 : Same-class constructor call allowed?

c# - MVVM 中的依赖注入(inject)和单一职责原则

java - 依赖倒置原则(适用于 Java)

c++ - 关闭时避免 wxFrame 销毁

c++ - 一种在 Qt 中管理 GUI 状态的 RAII

java - 如何从匿名内部类访问非最终变量?