【问题标题】:Static classes or instance pointers静态类或实例指针
【发布时间】:2017-07-19 08:01:26
【问题描述】:

背景故事:

目前我有一系列与游戏相关的三个课程。我之前使用 Unity 制作过游戏,您可以使用可在所有代码中访问的功能来访问相机等组件。然而,我当前的设置依赖于每个类的实例在其他类之间发送。请参阅以下内容:

class World{

};
class Game{
     Camera* camera;
     World* world;
};
class Camera{
     Game* game;
     World* world;
};

问题:

  • 这是设计不良的结果还是有时像这样的设置 这合理吗?

  • 我是否应该在当前设置上使用静态类,因为它 将澄清代码并且每个类的实例不超过一个 用过吗?

  • 使用静态类有哪些可能的缺点 实例?

编辑:为什么他们需要互相访问。

为什么相机需要世界: 相机需要访问世界,因为世界需要从相机的角度进行渲染。相机根据看到的内容触发世界渲染。渲染是由相机中的各种方法触发的,例如当它移动时。

当相机被绘制时,它会绘制它所看到的东西,例如世界。要绘制世界,相机需要访问世界。

为什么相机需要游戏: 游戏具有诸如 FPS 之类的值,Camera 使用这些值来显示调试信息的叠加。

【问题讨论】:

  • 每个类都需要访问整个其他具体类吗?抽象类会更聪明吗?这看起来像是“一切都依赖于其他一切”,而不是 SOLID/fluid/...通常的设计理念
  • 我肯定会研究任何缩放/基数问题。你的世界真的只有 1 个摄像头(甚至可能只有 1 个游戏吗?)。回答此类问题有助于塑造您的设计。如果您的世界有超过 1 个摄像头,您的世界(和游戏)如何区分各种摄像头?
  • @franji1 好点。但在这种情况下,我绝对知道每个人只会有一个。
  • @doctorlove 你能澄清一下使用抽象类是什么意思吗?它们确实相互依赖,但没有继承关系。
  • 具有纯虚函数的东西 - 然后您可以从每个中公开您想要使用的确切部分。

标签: c++ class oop c++11 static


【解决方案1】:

三个紧密耦合的类确实提出了一些有问题的设计选择。尝试更改您的代码,以便,例如,Camera 获得一个指针或对World 的引用,仅传入它实际需要处理World 的方法。还要考虑CameraWorld 是否真的需要指向Game 的指针。从概念上讲,如果Game 有一个World 和一个Camera,而不是所有三个对象都归其他人(谁)拥有,那么这将更有意义?

GameCamera 之间的关系仍然只是建议您应该将Game 甚至更好的相关数据从Game 作为方法参数传递给Camera 绘制方法。

【讨论】:

  • 我澄清了 Camera 需要访问其他两个类,请查看更新后的问题。你说得对,Game 应该同时携带 World 和 Camera 更有意义。
  • 我不太了解您的设计,您是在相机移动时渲染世界,还是每帧渲染一次?您的编辑似乎暗示了两者。
【解决方案2】:

如果您有任何类的静态(全局)实例,则可以从任何地方访问它,并且最终可能会出现“大泥球”,从而难以跟踪什么用途或需要什么。

所谓“SOLID”原则的一个想法是

“细节应该依赖于抽象”

现在引入额外的抽象基类(或支持它们的语言中的接口)可能看起来更加复杂,但它可能会帮助您找到每个对象的哪些部分需要从哪里收集,并允许您说引入另一个 Game未来。

一种方法可能如下:

#include <iostream>

class World {
public:
    int Info() { return 0; }
};
//An abstract base class
class IGame {
public:
    virtual ~IGame() = 0 {}
    virtual int FPS() = 0;
};

//One specific type of game
class Game : public IGame {
public:
    int FPS() { return 0; }
};


class Camera {
public:
    Camera(Game * game, World * world) : game(game), world(world) {
    }

    void Move() {
        //actually move first then ...
        Draw();
    }

    void Draw() {
        //This will show us what needs to be public in the other classes
        std::cout << world->Info() << '\n';
        if (game)
            std::cout << game->FPS() << '\n';

    }

private:
    IGame* game;
    World* world;
};

int main() {
    World world;
    Game game;
    Camera camera(&game, &world);
    camera.Move();
}

(依赖倒置原则)如this question中所述

这对你正在做的事情来说似乎有点过头了,但会让你更接近“一切都依赖于抽象的东西”,而不是“一切具体的东西都依赖于其他一切”。

【讨论】:

    猜你喜欢
    • 2013-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多