如何删除已注册/已添加的监听器?

时间:2011-01-20 22:25:35

标签: java design-patterns class-design

通常,允许您添加侦听器的接口还包括类似以下内容的remove方法。

interface SomeInterface {
  addListener( Listener) 
  removeListener( Listener );
}

然而,这有几个原因。

  • 可以将尚未删除的侦听器传递给SomeInterface.removeListener()。
  • 也可以打电话 SI.removeListener()没有监听器时 避难所登记。一个人不应该 甚至可以在做之前调用删除 添加。
  • 这也意味着必须保持Listener和SI引用的句柄,以便在稍后阶段删除。

我有一个建议,我认为有效解决了这三个问题,但是我希望听到其他人从他们的想法和建议中吸取教训,这些建议可能比我自己的解决方案更优雅。

4 个答案:

答案 0 :(得分:2)

我不认为你的问题是真的。

当然,您可以使用no-arg方法从addListener返回一个对象以删除该侦听器。实际上,这将简化完整层的注销。但我不认为这是必要的。

答案 1 :(得分:2)

我的建议是让AddListener方法使用一种方法返回类型为ISubscriptionCanceller的对象:CancelSubscription和可能的SubscriptionActive属性。此对象将包含取消给定订阅所需的所有信息,订阅是存储在数组,链接列表还是尚未发明的某些新数据结构中。当然不可能尝试取消尚未请求的订阅,因为没有必要的ISubscriptionCanceller这样做。

答案 2 :(得分:1)

我相信这并不像你想的那么糟糕。有许多类使用此模式。如果你真的想要你可以让removeListener()返回true / false(如果真的删除了侦听器,则为true)或者在尝试删除未注册的侦听器时抛出异常(例如IllegalStateException)。但你真的想这样做吗?如果发生异常,你会做什么?在大多数情况下它并不重要,所以我认为制作很简单。你的界面还可以。

您还可以添加方法

Iterator listeners()

返回迭代器。因此,您可以在使用Iterator.remove()进行迭代时删除侦听器。至少在这种情况下,您将无法删除未注册的侦听器。

答案 3 :(得分:-1)

我认为你的许多基本假设是错误的。让我们考虑一下Java中的替代方法,即在注册侦听器之前,removeListener不是类中的方法。

  1. 这在Java中是不可能的; Java不是动态语言(忽略反射)
  2. 即使有可能,就像在javascript中一样,你会如何处理你可以添加不同类型的监听器的事实?您是否为每种类型提出了删除方法?
  3. 通常,如果传入一个尚未注册到某种观察类的侦听器,该方法将不执行任何操作,并且可能返回指示成功或失败的布尔值。这很好,很好理解。我完全拒绝这句话:“当没有监听器登记时,也可以调用SI.removeListener()。在进行添加之前,不应该调用remove。”