【问题标题】:In Java, what's the best way to make class A do something when an event happens in class B without class B knowing of class A's existence?在Java中,当B类中发生事件而B类不知道A类的存在时,让A类做某事的最佳方法是什么?
【发布时间】:2019-12-10 23:13:39
【问题描述】:

我正在制作一个小游戏,我有一个 PlayScreen,它有一个 GameWorld,它有一个 Player。现在,每当玩家触摸传送块时,我将 PlayScreen 调暗,然后 Player 传送,然后 PlayScreen 再次亮起。

目前为了实现这一点,我在 Player 中添加了 boolean inTeleportAnimation。然后 PlayScreen 检查 update() 内的每一帧是否播放器处于传送动画中,如果是,它开始调暗屏幕。现在这看起来很好,因为它只检查 1 个布尔值/触发器。但稍后可能会有很多不同的触发器让 PlayScreen 执行某些操作(例如调暗屏幕)。让playScreen.update() 每帧检查每个触发器/布尔值可能是个坏主意,因为这意味着我需要为每个可能的触发器使用另一个 if 语句。我也不想让 PlayScreen 和 Player 的关系是双向的。

实现这一目标的最佳或“正确”方法是什么?

【问题讨论】:

  • 观察者模式可能吗?
  • Publish-Subscribe 模式。实际上,此时在您的情况下,观察者可能更好。
  • 那么在这种情况下 Player 将是可观察的,对吗?但是 PlayScreen 是主要的游戏循环类,它基本上每帧都会更新整个 GameWorld,所以它也会更新 Player。如果我让 Player 成为 observable 并让 PlayScreen 成为观察者,这基本上会创建一个双向关系。不知道我是否遗漏了什么,所以如果我错了,请纠正我。

标签: java relationship


【解决方案1】:

我会使用observer design pattern 来解决这个任务。它应该可以解决您希望避免双向耦合的问题,因为 PlayScreen(在这种情况下为观察者)会根据需要通知 Player(在这种情况下为 observable)的更改,但否则不会参考,或与播放器的任何其他类型的紧密耦合。

如果您使用的是 Java,正如这篇文章的标签所示,这里有一个 simple example in Java 应该用来演示它的使用。

【讨论】:

  • 所以使用这种模式,observable 有它的观察者的实例,但是观察者也在他们的 update(Observable obs) 方法中更新了 observable?观察者从哪里得到可观察的?抱歉,我是这种模式的新手,所以我还是有点困惑。
  • 作为旁注,如果有一个带有静态 PlayScreen 实例的静态类 PlayScreenDimmer 以便我可以从任何地方调暗 PlayScreen 是否是不好的做法?
  • observable 不会在其类定义中包含对其观察者的任何实例的引用。唯一的(松散耦合的)关联发生在对(参见引用的示例)Observable#addObserver 的调用中。这将创建一个观察者集合(PlayScreen,或您添加的任何其他实现 Observer 接口的对象),这些观察者有兴趣接收由可观察播放器(通过 Observable#notifyObservers 方法)发布的更新(通过 Observer#update 方法)。
  • 关于您的旁注问题,为什么不向您的 PlayScreen 类添加一个非静态 #dim 方法,当通过 Observer#update 方法接收到更新时调用该方法?
  • 好的,谢谢,我会多研究一下如何实现这个模式。是的,静态 PlayScreenDimmer 更像是观察者模式的替代品。当然,使用观察者模式我不需要任何静态方法。
【解决方案2】:

如果您的播放器设置了一个全局标志,该标志会在播放器中发生更新时打开(例如,当设置 inTeleportAnimation 时,此标志也会设置,其他标志相同)并且在 PlayScreen.update( ) 处理更新,这样 Player 不知道 PlayScreen 并且您可以避免在每一帧中进行不必要的检查。但我没有看到避免检查每个条件的方法(假设全局标志表示更新)。

【讨论】:

  • 所以你基本上是指 2 个标志,1 个通知事件已经发生,然后 PlayScreen 可以找到另一个指定发生了哪个事件的标志?这也是我的想法,但我不确定这是否是不好的做法..
  • 是的,这就是我的意思,在这种情况下,这种关系是一种方式。拥有全局标志更多的是一种性能优化。
猜你喜欢
  • 1970-01-01
  • 2013-06-12
  • 1970-01-01
  • 2022-12-18
  • 1970-01-01
  • 1970-01-01
  • 2021-11-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多