0

我正在设计一个小型库,有时我写了几行,感觉不对,所以我想得到一个实验过的 java 程序员的意见/建议。

我有一个处理 3 个不同事件的侦听器,在我的一个班级中,我实现了实际触发事件的方法

所以我一开始做的是这样的:

 protected final void fireOperationStarted(){
     OperationEvent event = new OperationEvent(this);

    for (OperationListener listener : listeners) {
        listener.operationStarted(event);
    }
}


protected final void fireOperationEnded(){
    OperationEvent event = new OperationEvent(this);

    for (OperationListener listener : listeners) {
        listener.operationEnded(event);
    }

//omitted the 3rd method on purpose

但是这段代码感觉不对,因为如果有人想实现自己的事件,他们基本上需要访问整个侦听器数组列表(CopyOnWriteArraylist)并一次又一次地编写逻辑。

所以我选择的是一个带有单一方法“fire”的 Fireable 接口。这就是我所做的:

protected final void fireOperationStarted(){
fireOperation(new Fireable(){

    @Override
    public void fire(OperationListener listener, OperationEvent event) {            
        listener.operationStarted(event);
    }

});
}

 protected final void fireOperationEnded(){
fireOperation(new Fireable(){

    @Override
    public void fire(OperationListener listener, OperationEvent event) {            
        listener.operationEnded(event);
    }

});
}

protected void fireOperation(Fireable fireable){

    OperationEvent event = new OperationEvent(this);

    for (OperationListener listener : listeners) {
    fireable.fire(listener, event);
    }
}

我想听听你的意见,我个人认为它比第一个实现更好,即使仍然有很多样板代码。也许有更好的方法来做到这一点?我查看了 java.awt.events 包源代码以了解它们如何处理多个事件以及它们如何触发它们,但这对于我的需求来说似乎太复杂了。

我还想知道的一件事是关于 Java 8 中的 lambda 表达式,如果我在不导入任何 Java 8 包的情况下使用它们并进行编译,它会在 JRE7 上工作吗?

最终使用 JDK8 使我的代码更干净可能会很棒。

谢谢你的帮助 !

4

1 回答 1

0

我认为你的第一个例子更好。 listeners必须是一个实例字段,因此每个人都可以轻松使用。

(您可能在 OperationListener 中只有一个方法,并在 OperationEvent 中使用一个值来确定涉及哪个操作。然后您的方法都可以将正确的事件传递给一个调用该一个侦听器方法的方法。)

您的第二个想法很有趣,但对于在一个类的一个实例中使用,我认为它是矫枉过正的。

存储监听器的方式有很多种。如果您没有太快地添加和删除它们,那么 ArrayList 很好。如果有任何机会在不同的线程上添加和删除它们并且您经常调用侦听器,那么 CopyOnWriteArrayList 会好得多。

不要太担心“样板”。对于低级代码,Java 倾向于冗长但简单。您的第一个示例中的两个循环要求以某种方式组合,但在您获得更多for它们之前不值得担心。

Lambdas 将减少您的代码行数(如果您使用简单的代码;我的 C# lambdas 最终都会运行 20 行或更多行;还可能是匿名类!),但它们会在语言手册中添加大量页面。但是,直到 JRE 8 才出现 lambda。

于 2013-07-09T18:36:02.217 回答