适用于全局类的面向对象的结构

时间:2012-05-10 01:12:57

标签: actionscript-3 oop design-patterns singleton audio

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

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

3 个答案:

答案 0 :(得分:1)

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

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

我的推理有些注意事项:

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

反正;这是我的观点,以抵消将出现在这里的可能相反的答案。

答案 1 :(得分:0)

它们很糟糕,因为全局变量很糟糕的原因相同,一些有用的读物​​:

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

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

答案 2 :(得分:0)

“经理”通常是非常复杂的类,因此可能违反Single Responsibility Principle。用鲍勃·马丁叔叔的话来解释:任何时候你都觉得自己想要把某个东西称为“经理” - 这就是代码味道。

在您的情况下,您至少要处理三种不同的职责:

  1. 加载和存储声音。
  2. 在需要时播放声音。
  3. 控制输出参数,例如音量和平移。
  4. 其中两个可能被实现为单例,但是你应该总是非常小心这个模式,因为in itself, it violates the SRP,如果使用错误的方式,它会导致你的代码紧密耦合(相反,你应该使用Dependency Injection模式,可能通过框架,例如SwiftSuspenders,但not necessarily):

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

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

    每个SoundPlayer都可以同时包含主SoundController及其内容特定的引用,以及 - { - 1}}。 这些,然后可以是静态引用:因为它们都是你自己的声音插件的所有部分,它们通常会被部署为一个包,因此紧耦合不会这里有很多损害 - 但重要的是,不要越过插件的边界:实例化SoundModel分区中的所有内容,并将实例传递给所有需要它们的类;只有Main界面显示在您的游戏逻辑等中