看到典型的addXXXListener()返回void! 无论是UI框架(如Swing)还是服务器端框架,我都将其视为一种全面的实践。
对于前: 上课:AsyncContext
public void addAsyncListener(AsyncListener listener);
public void addActionListener(ActionListener l)
还有其他许多例子......
我们是否有兴趣知道添加侦听器调用是否成功完成? 如果组件处于无法添加侦听器的状态,该怎么办?
例如:考虑Guava库[ListenableFuture](http://guava-libraries.googlecode.com/svn/tags/release08/javadoc/com/google/common/util/concurrent/ListenableFuture.html#addListener(java.lang.Runnable,java.util.concurrent.Executor))
它有一个
void addListener(Runnable listener, Executor exec);
它的行为是在Future的计算完成时执行监听器。 他们采取的方法是,如果Future已经完成,那么将立即调用监听器。即使未来完成了年龄的回归。 用户没有迹象表明他们在已经完成的未来上不必要地调用addListener()!
我认为addListener()应该能够返回一个值(boolean?),该值表示是否可以成功添加侦听器,并且如果无法添加侦听器,则让调用者进行处理!
我知道必须有一些理由为什么所有addListeners都是这样编写的。 我只是不知道为什么?
答案 0 :(得分:5)
这些方法通常只是将您的侦听器添加到列表中。它无法工作的环境通常不在你的控制范围之内(例如,考虑内存错误)并且无论如何都会触发异常。
例如,Collection#add
返回布尔值的原因是某些实现只会在满足某些条件时添加项目(例如,如果项目是重复的,则不会添加项目)。请注意this is the only situation when Collection#add
will return false(其他原因会触发异常):
如果一个集合因为已经包含该元素的原因而拒绝添加特定元素,那么它必须抛出一个异常(而不是返回false)。这保留了在此调用返回后集合始终包含指定元素的不变量。
这可能被认为对addListener
不太有用。
答案 1 :(得分:1)
在所有这些情况下,没有可能无法添加侦听器。
即使未来的岁月已经完成。
那么如果未来的年龄已经完成了怎么办呢?如果你想为Future
添加一个监听器,那么无论是在很久以前还是在将来,你都希望对该结果做一些事情。
答案 2 :(得分:1)
如果可以期望调用者对该信息采取行动,则该约定是将信息返回给调用者。
ListenableFuture是大多数addXXXListener()调用的一个非常不同的用例。预期这些将立即返回并在正常操作中100%成功(例如,仅向一些内部列表结构添加侦听器)并且没有可操作的信息返回给调用者。 (但是,在非正常操作中,您可能会期望它抛出未经检查的异常)。
一种可能的变化是将其视为一个mutator操作,并扩展通常的Collection模式,如果addXXXListener()调用修改了内部数据结构,则返回一个布尔值。虽然如果调用者不知道它是否已经添加了自己,这只会返回有用的信息......