8

我正在尝试自学编程。我以与大多数人相同的方式开始;制作小而杂乱的应用程序和游戏,以不那么简单的方式做简单的事情。最近,我一直在尝试通过编写一个稍微复杂一些的游戏来迈出下一步,该游戏使用 OOP 设计来编写更好、更模块化的代码!

我遇到的主要问题是我的主要 StateManager (FSM) 类的设计(在介绍/菜单/游戏/等屏幕状态之间切换)。高高在上,我只见过两种设计方法:

  • 使用 switch/case 语句 + 枚举在状态之间切换..

  • 制作一个单例 FSM 类来处理向/从向量推送/弹出状态。

现在,我的问题是,switch case 语句非常重复且笨拙,这与我使用这个项目来自学 OOP 的目标背道而驰。

我的第二个也是更大的问题是“单身”建议。

正如我之前所说,我正在努力自学,在编程方面我还有很多东西要学,尤其是在 OOP 和设计模式等领域。我遇到了一个问题,对于我发现的每一个“单例都是邪恶的”线程和讨论,我发现人们在他们的代码中使用单例来制作“引擎”类和 FSM 的教程和参考资料一样多。这是一个非常一致的混合信息。

我想我只是不明白为什么......即使你只想/打算拥有一个类的单个对象,为什么有必要/有益于将构造函数设为私有并创建一个单例?我读过很多关于单例有多糟糕,它们本质上是如何全局的,它们是如何阻碍多线程的,以及有多少程序员认为它们被过度使用或只是简单的糟糕设计......但我看到一个又一个例子使用它们的人,很少有反例显示替代方法。

普通班就不能做同样的事情吗?明确限制创建实例的目的是什么?我只听说过关于单例的负面消息,但人们似乎经常使用它们……我是否完全错过了单例和 OOP 的一些内容?

单例的使用只是一种趋势,还是人们称单例为“邪恶”的一种趋势?我该如何解决这个问题..?开关/外壳 FSM 和单例 FSM 之间没有什么东西吗?有人不能以完全相同的方式设计他们的程序的状态系统而不使他们的任何类成为单例吗?那会改变什么吗?[困惑]

4

3 回答 3

6

普通班就不能做同样的事情吗?明确限制创建实例的目的是什么?我只听说过关于单例的负面消息,但人们似乎经常使用它们……我是否完全错过了单例和 OOP 的一些内容?

不,我相信您走在正确的轨道上:绝对没有理由阻止创建两个实例。宇宙不会因此而内爆。

这是一个完全不必要的限制。由于您必须手动编写该限制,因此拥有它非常愚蠢(如果您必须编写代码来解除它,那将是另一回事)。

我想如果创建第二个实例,可能会出现一些奇怪且罕见的情况,即宇宙确实会内爆,但这听起来很牵强。无论如何,这并不能证明单身人士在整个互联网上的盛行是合理的。

我无法真正解释为什么人们经常使用它们而不侮辱这些人的推理能力,所以我会避免这样做。

有人不能以完全相同的方式设计他们的程序的状态系统而不使他们的任何类成为单例吗?那会改变什么吗?

它唯一改变的是,通过使其成为单例,您可以防止自己为单元测试创​​建一次性实例。其他一切都一样。

于 2012-08-09T11:19:51.057 回答
3

通常情况下,没有一个简单的答案。在 C++ 中,单例模式还管理初始化问题的顺序,如果要在静态对象的构造函数中使用,这一点很重要。并且在某些类型的对象中,多个实例只能是编程错误;如果你能阻止他们,为什么不呢。

另一方面,我很难想象一个StateManager类应该是单例的情况。它绝不是管理某些独特的资源或某些元功能(例如日志记录),其本质上必须是独特的。而且我也无法想象它被用于静态对象的构造函数中。

诸如“单身人士不好”之类的说法非常具有误导性;对于某些事情,它们是最合适的解决方案。但仅仅因为它们绝对不坏并不意味着它们在任何地方都是合适的。它们解决了一个特定的、非常有限的问题。当你需要解决这个问题时,使用单例是不好的。但是(几乎所有事情都是如此),在不合适的时候使用它是不好的。

于 2012-08-09T12:09:30.693 回答
1

我不明白为什么 FSM 类应该是单例的。有很多真实世界的 FSM 系统没有单例,见鬼,有一些状态实例在 SM 遍历状态时被创建和销毁,并且状态机本身就是一个状态,可以轻松组合分层状态机。

在一个复杂的应用程序中,您将拥有多个状态机,其中一些会突然出现或消失。例如,处理客户端-服务器交互的那些,必然有多个与客户端来来去去的实例。其他一些可能会受益于组合多个分层状态机,其中一些可能会在许多地方重复使用。因此,您将状态机作为单例的想法对我来说是愚蠢的。例如,您可能在封装您的应用程序的单例应用程序类中拥有特定状态机的实例,但这远非单例类状态机。

要全面了解各种状态机实现技术,包括平面 FSM 和分层状态机 (HSM) 之间的对比,您需要查看 Miro Samek 的PSICC2书。他有大量可免费下载的文章,其中解释了常用技术。

可用于 UI 的分层状态机的合理 C++ 实现在 Qt 的状态机框架中可用。

于 2012-08-09T11:50:55.490 回答