我对单身人士有过分杀戮吗?

9 c++ opengl

我对C++很陌生,正在编写一个跨平台(桌面/移动)2D游戏引擎...我的问题是,我是否以适当的方式使用单身,如果没有,是否有替代方案?

基本上我的引擎有几个组件围绕单个对象构建.例子:

VBOManager(Singleton)
这个"管理器"基本上负责分配,当然还有"管理"用于存储纹理映射和顶点坐标的vbo.我通过这个对象控制"读/写",所以我可以缓存由其他对象写入vbo的数据并返回指针(避免存储重复数据,如具有相同映射和顶点坐标的500个精灵).

TextureManager(Singleton,自我解释)

GLUtils(Singleton)
我几乎用它来统一基于当前平台不同的常见GL调用,如GL或GLES.例如,GLU函数(libglu不在android上,所以我有一个自定义实现)

Graphics(Singleton)
用于处理窗口初始化和调整大小,全局帧率管理,视口初始化等操作.

InputManager(Singleton,自我解释)

无论如何,所以我在这里回顾所有这些,我开始感觉真的,非常脏.我确实认为,鉴于给定对象的要求和功能,它是合理的.但另一方面,我是一个新手,而且我觉得这个"模式"在我的代码中如此猖獗是不对的.如果后者确实如此,那可能是另一种选择?

Nic*_*las 7

在开始之前,我想明确我们正在谈论的内容,以便我们都在同一页面上.单身人士是:

  1. "一个对象,"这意味着它具有某种内部状态,该状态由直接外部访问封装.它有一个生命周期:它在程序执行的某个时刻创建,并在稍后的某个时刻被销毁.
  2. "其中只能创建一个实例,"这意味着有一些明确的机制可以强行阻止创建多个实例.在程序的执行中,构造函数和析构函数将被调用不超过一次.
  3. "这是全球可访问的." 创建实例后,可以通过全局函数调用或类的公共静态成员访问该实例.

全局对象不是单身人士; 它只是一个全球性的对象.如果可以制作多个,则不是单身.

现在定义已经不在了:

VBOManager(Singleton)

我无法想象这个物体如何以任何有意义的方式起作用.就OpenGL而言,缓冲对象是独立的构造.他们彼此没有关系.所以我不明白为什么你需要一个处理所有这些的经理.

我可以理解有一个专门的包装缓冲区对象类来处理流缓冲对象.有几种方法可以进行流式传输,有些方法比其他方式更有效.因此将它包装在一个对象中是有意义的.

但是拥有一个全局缓冲区对象管理器是没有意义的.缓冲对象应该彼此独立.或者,如果有的话,它们应该依赖于其他对象,如网格(多个网格对象可以引用相同的缓冲区).但是您不需要拥有全局缓冲区对象管理器.

我可以理解有一个可以添加和检索的命名对象的存储库.但是我不明白是否需要将它用于像这样的特定对象类型.而且它需要成为一个全球性的单身人士......是可疑的.

我发现单身人士最适合从根本上独特的概念.有一个文件系统,因此有一个全局文件系统是有意义的.OpenGL本身是全局的(由于其基于C的特性),尽管如此,它仍然可以切换渲染上下文.如果有两个东西是有道理的,那么单身可能不是最好的方法.

即使您只使用单个缓冲区对象,并且有一个管理器,也不需要将此类设为单例.如果您愿意,可以将其设置为全局,但不需要强制阻止用户创建此类的多个实例.如果以后,你想拥有多个缓冲区对象管理器(并可能支付性能价格),那就这样吧.

GLUtils(单身人士)

为什么这是一个对象?Singleton模式指的是一个对象,任何时候都只能有一个实例.效用函数只是全局函数.

C++不是Java.您不必将所有内容都放在课堂上.全局功能设计也不错.实际上,它们是适当的好设计.如果函数不需要访问任何状态(在其参数和它可能调用的任何其他函数之外),则不需要它成为对象的一部分.

图形(单身)

这是人们可以争辩单身人士有意义的事情.它是一个有国家的生物.并且您明确地不希望在您的应用程序中使用多个.

但是,考虑一下.拥有多个人是错误的吗?你多久会绕过这个Graphics物体?需要多少代码才能在Graphics对象级别上工作?我猜不是很多.一些基本的初始化代码,就是这样.

因此,虽然它是可辩护的,但没有必要.这不是一个需要成为单身人士的概念.此外,通过能够拥有多个,您可以随时删除它并创建一个新的.这使您的应用程序能够更轻松地重建窗口.

这样做的一个缺点是可能同时拥有两个Graphics物体.这涉及到处理OpenGL上下文.由于OpenGL上下文是全局状态,因此具有多个Graphics对象可能会导致问题,因为两者都有自己的上下文.您需要一些方法将特定Graphics对象设置为当前对象,它将自身绑定为当前OpenGL上下文(并检索它需要的任何函数指针).