LinkSet – Java 事件的替代方法





4.00/5 (9投票s)
LinkSet 是一个小型库,旨在帮助程序员摆脱声明监听器接口的麻烦。
引言
LinkSet 是一个小型库,旨在帮助程序员摆脱声明监听器接口的麻烦。它利用了 Java 5 的特性,并被设计为传统 "监听器接口 + 匿名类" 解决方案的直接替代品。
Java 是一门很棒的语言,比 C# 干净得多。但在监听器方面,它落后于 C#。每次用 C# 编程时,我都会想:“我希望 Java 也有委托。” 我也喜欢 Qt 的信号/槽方法。 很久以前,我思考过:“我能否创建比那些语法上可怕的匿名类更干净、更易于使用的东西?” 于是 LinkSet (github.com/lbownik/linkset) 诞生了。 LinkSet 是一个小型库,它利用 Java 5 的特性来提供一种简单易用的监听器机制,该机制不需要监听器接口或匿名类。
LinkSet 的特性
在设计 LinkSet 时,我希望它
- 易于使用 - 库的使用应尽可能少地增加编程工作量。这意味着:不需要监听器接口,也不需要特殊的构建步骤。
- 灵活 - 实例方法和静态方法都可以是事件处理程序。
- 无侵入性 – 它不要求事件处理对象实现任何特定接口,并且事件处理方法可以是
private
。 - 易于学习 – 它仅由几个直观的类组成,易于使用
- 体积小,速度合理
- 免费 - LGPL 许可证
我希望我满足了这些要求。
使用 LinkSet
要开始使用 LinkSet,您需要访问项目的网站 (github.com/lbownik/linkset) 并下载 jar 文件。然后将其包含到项目的类路径中即可。
事件源
LinkSet 旨在简化事件源和事件处理程序类的开发。以下代码展示了一个事件源的类。
此代码展示了如何实现一个可以被监听器观察的类。
package com.mycompany.project1;
import org.linkset.DefaultListenerManager;
import org.linkset.ListenerManager;
import org.linkset.MethodPointer;
public class EventSource {
// a multi-listener manager
private final DefaultListenerManager clickListeners =
new DefaultListenerManager();
// a single listener pointer - useful when a return value is
// needed
private MethodPointer vetoableListener;
// some constants
public final static int LeftButton = 0;
public final static int RightButton = 1;
public ListenerManager clickdListeners() {
return this.clickListeners;
}
public void setVetoableListener(MethodPointer pointer) {
this.vetoableListener = pointer;
}
public void doStuff() throws Exception {
//fire click event
this.clickListeners.invokeAll(LeftButton);
// check if we can change state if we want to
final boolean canChangeState
(Boolean)this.vetoableListener.invoke();
if(canChangeState == true) {
}
}
}
该类声明了两个 private
字段。 clickListeners
是 DefaultListenerManager
类的一个对象。此类是事件处理程序的集合,当事件发生时应调用这些事件处理程序。 方法 clickListeners()
允许客户端通过在 ListenerManager
接口中定义的 add(…)
方法连接其处理程序。 这样,客户端可以使用类似的代码轻松连接到事件源
Source.clickListeners().add(….);
第二个字段名为 vetoableListener
是 MethodPointer
类的一个对象。此类实现了一个事件处理程序方法指针,当只需要一个监听器且其返回值在后续计算中(例如在可否决的观察者模式中)是必需的时,可以使用此指针。 方法 setVetoableListener(...)
允许客户端设置指针引用。 方法 doStuff()
包含使用适当的 invokeAll(…)
和 invoke(…)
方法调用所有监听器的代码。
事件处理器
以下代码展示了如何实现一个提供监听事件的方法的类。
package com.mycompany.project1;
import org.linkset.HandlerMethod;
import org.linkset.MethodPointer;
public class EventHandler {
private EventSource provider = new EventSource();
public EventHandler() {
// we set a reference to an object and handler method id
this.provider.clickdListeners().add(this, "clickListener");
// in case of static methods we need to pass a Class object
// reference
this.provider.setVetoablePointer(new
MethodPointer(this.getClass(), "canChange"));
}
@HandlerMethod(id = "clickListener")
private void clickListener(int button) {
System.out.println("Button click=" + button);
}
@HandlerMethod(id = "canChange")
private static boolean canChange() {
System.out.println("Can change?");
return false;
}
public static void main(String[] args) throws Exception {
EventHandler handler = new EventHandler();
handler.provider.doStuff();
}
}
该类声明了两种方法。 private
实例方法 clickListener(…)
是在单击事件发生时调用的方法。它使用带有唯一 id
的 HandlerMethod
注解进行注释。此 id
用于
this.provider.clickdListeners().add(this, "clickListener");
指向所提供对象中的正确方法。提供的标识符必须在类范围内是唯一的,但可以在不同的类中重复使用。
当调用 vetoableListener
时,将调用 private static
方法 canChange()
。代码
this.provider.setVetoableListener(new MethodPointer(this.getClass(),"canChange"));
设置源对象所需的指针。值得注意的是,当提供 static
方法的 id
时,LinkSet 需要一个 Class
对象作为事件目标。
摘要
LinkSet 库是一个小型的 Perl,它形成于对 Java 默认处理事件方式的持续 раздражение(irritation)。 它小巧、简单且易于使用。 它是无需任何新语法结构(如闭包)即可直接替换的方案。
历史
- 2010 年 2 月 19 日:初始发布