使用单例类进行声音管理的优缺点是什么?
我担心它在结构上是非常反 OOP 的,并且不想潜在地陷入错误的道路,但有什么更好的选择呢?
使用单例类进行声音管理的优缺点是什么?
我担心它在结构上是非常反 OOP 的,并且不想潜在地陷入错误的道路,但有什么更好的选择呢?
这是一个尴尬的话题,但我会说声音管理器样式类是不应该初始化的类的良好候选者。
同样,如果键盘输入管理器样式类是一个完全静态的类,我会觉得没问题。
我的推理的一些注意事项:
无论如何; 这是我的观点,以抵消可能出现在这里的相反答案。
它们之所以不好,是因为与全局变量不好的原因相同,一些有用的阅读:
http://blogs.msdn.com/b/scottdensmore/archive/2004/05/25/140827.aspx
更好的选择是将它作为应用程序类的成员,并将它的引用传递给只需要处理声音的模块。
“经理”通常是性质非常复杂的类,因此可能违反单一职责原则。套用鲍勃·马丁叔叔的话说:任何时候你觉得自己很想把某个类称为“经理”类——这就是代码的味道。
就您而言,您至少要承担三个不同的职责:
其中,两个可能被实现为单例,但你应该始终非常小心这种模式,因为它本身就违反了 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.