2

使用单例类进行声音管理的优缺点是什么?

我担心它在结构上是非常反 OOP 的,并且不想潜在地陷入错误的道路,但有什么更好的选择呢?

4

3 回答 3

1

这是一个尴尬的话题,但我会说声音管理器样式类是不应该初始化的类的良好候选者。

同样,如果键盘输入管理器样式类是一个完全静态的类,我会觉得没问题。

我的推理的一些注意事项:

  • 您不会期望有多个实例可以处理所有声音。
  • 它很容易访问,在这种情况下这是一件好事,因为声音看起来更像是一个应用程序级别的实用程序,而不是只能由某些对象访问的东西。例如,将游戏的 Player 类设为静态将是一个非常糟糕的设计选择,因为游戏中几乎没有其他类需要直接引用 Player。
  • 例如,在游戏的上下文中,想象一下需要引用声音管理器实例的类的数量;敌人、效果、物品、用户界面、环境。真是一场噩梦——拥有一个静态声音管理器类消除了这个要求。
  • 我能想到的情况并不多,在什么情况下访问声音根本没有意义。几乎任何东西都可以触发声音 - 鼠标的移动、爆炸效果、对话的加载等。静态类与应用程序中的大多数其他类几乎没有相关性或用途时是不好的- 声音。

无论如何; 这是我的观点,以抵消可能出现在这里的相反答案。

于 2012-05-10T03:32:47.050 回答
0

它们之所以不好,是因为与全局变量不好的原因相同,一些有用的阅读:

http://blogs.msdn.com/b/scottdensmore/archive/2004/05/25/140827.aspx

更好的选择是将它作为应用程序类的成员,并将它的引用传递给只需要处理声音的模块。

于 2012-05-10T01:51:33.873 回答
0

“经理”通常是性质非常复杂的类,因此可能违反单一职责原则。套用鲍勃·马丁叔叔的话说:任何时候你觉得自己很想把某个类称为“经理”类——这就是代码的味道。

就您而言,您至少要承担三个不同的职责:

  1. 加载和存储声音。
  2. 需要时播放声音。
  3. 控制输出参数,例如音量和声像。

其中,两个可能被实现为单例,但你应该始终非常小心这种模式,因为它本身就违反了 SRP,如果使用错误的方式,它会导致你的代码紧密耦合(相反,你应该使用依赖注入模式,可能通过框架,例如SwiftSuspenders,但不一定):

  • 加载和存储声音本质上是一项严格的数据相关任务,因此应该由 处理,SoundModel每个应用程序只需要一个实例。
  • 控制输出参数是您可能希望在中央位置处理的事情,以便能够更改全局音量设置等。这可以实现为单例,但更可能是树状结构,其中主SoundController处理全局settings,还有几个childSoundControllers负责更具体的上下文,比如UI音效、游戏音效、音乐等。

播放声音会在很多地方以多种不同的方式发生:可能有循环(您需要保留对它的引用以便以后能够停止它们),或效果声音(通常很短并且可以播放)只有一次),或音乐(每首歌曲通常播放一次,但需要在到达结尾时自动开始后续歌曲)。对于这些变体中的每一个(以及您想出的任何变体),您都应该创建一个不同的类,该类实现一个通用SoundPlayer接口,例如LoopSoundPlayerImpl, SequentialSoundPlayerImpl,EFXSoundPlayerImpl等。接口应该像play(), pause(),一样简单rewind()- 您以后可以轻松地交换它们,并且对于紧密耦合的库不会有任何问题。

Each SoundPlayer can hold a reference to both the master SoundController an its content-specific one, as well as - possibly - the SoundModel. These, then can be static references: Since they are all parts of your own sound plugin, they will usually be deployed as a package, and therefore tight coupling won't do much damage here - it is important, though, not to cross the boundary of the plugin: Instantiate everything within your Main partition, and pass on the instances to all classes, which need them; only have the SoundPlayer interface show up within your game logic, etc.

于 2012-05-10T05:45:37.573 回答