0

我一直在尝试在 java 中做一些“简单的事情”,在 javascript 中看起来像:

// Main class
var model = new Model();
this.callback = function(e){/* do something */}
model.addListener("change", callback);

那么在java中我到目前为止发现的是从java.util.Observer派生的Main类和从java.util.Observable派生的Model;然后,当模型将调度事件时,它将调用 Main 类的 update 方法。我发现真的很丑,一点也不优雅。我什至想不出我该如何处理它;

有没有更清洁和灵活的方法,也许有一些库可以帮助我,因为我还没有找到任何可以接受的关于如何做到这一点的教程?

多谢

好吧,到目前为止我所管理的,我非常喜欢它,而不仅仅是为简单的事件创建“空”类(但仍然不好,至少对我来说):

private ArrayList __items;
public void addListener(Method method, Object object){
    this.__listeners.add(new Object[] {method, object});
}


public void dispatch(){
    int i = this.__listeners.size();
    Method method;
    Object context;
    while(i>0){
        i--;
        method = (Method)(this.__listeners.get(i))[0];
        context = (Object)(this.__listeners.get(i))[1];
        try{
            method.invoke(context);
        }catch(java.lang.reflect.InvocationTargetException e){

        }catch(java.lang.IllegalAccessException e){

        }
    }
}

然后我这样使用:

Gifts gifts = prendastotty.PrendasTotty.getMain().getLoggedUserGifts();
Class[] parameterTypes = new Class[0];
try{
    Method m = Home.class.getMethod("__updateTable", parameterTypes);
    gifts.addListener(m, this);
}catch(NoSuchMethodException e){

}

这是泄漏/反模式/错误吗?

4

3 回答 3

2

我必须说我在跟上您的代码时遇到了一些麻烦,因为在我的脑海中有些东西没有意义(从 Java 的思维方式,或者至少是我的Java 思维方式)。所以我希望我能正确理解你并能帮助你。

让我们首先以您的简单示例为例:

var model = new Model();
this.callback = function(e){/* do something */}
model.addListener("change", callback);

例如,在 Java 中,一个好的方法是:

public interface ModelListener {
   public void execute(Model context);
}

public class Model { 
    private List<ModelListener> listeners;

    public Model() {
      this.listeners = new ArrayList<ModelListener>();
    }

    public void addListener(ModelListener listener) {
      this.listeners.add(listener);
    }

    public void dispatch() {
      for (ModelListener listener: listeners) {
        listener.execute(this);
      }
    }

}

通过这种设计,您现在可以做以下两件事之一:

使用匿名类

在 Java 中,最常见的情况是您的所有类都有一个名称,尽管在某些情况下您可以创建匿名类,但这些基本上是内联实现的类。由于它们是内联实现的,因此它们通常仅在它们很小并且已知它们不能重复使用时使用。

例子:

Model model = new Model();
model.add(new ModelListener() {
     public void execute(Model model) { /* do something here */ }
});

请注意新ModelListener对象是如何创建的(它是一个接口)以及execute内联提供的实现。那是匿名类。

接口实现

您可以创建实现您的接口的类并使用它们而不是匿名类。当您希望侦听器可重用、具有赋予代码语义意义的名称和/或它们的逻辑不仅仅是几行代码时,通常会使用这种方法。

例子:

public class LogListener implements ModelListener {

 public void execute(Model model) {
   // Do my logging here
 }
}

Model model = new Model();  
model.addListener(new LogListener());

边注

As a side note, I saw that the method you were trying to bind as a listener was called __updateTable are you by any chance trying to detect object's changes so you can commit them to the database? If so I strongly suggest you to look at some ORM frameworks such as Hibernate or JPA they'll keep all that hassle from you, keeping track of changes and committing them to the database.

Hope it helps, regards from a fellow portuguese StackOverflow user ;)

于 2012-12-06T23:19:46.377 回答
0

您会发现尝试将 javascript 意识形态直接映射到 java 有点困难。他们的基本哲学是不同的。没有更明确的代码和期望,很难给你一个更清晰的答案。这是GWT(编写java)中的代码示例,它将单击处理程序附加到按钮。

希望这可以帮助您入门。

 myButton.addSelectionListener(new SelectionListener<ComponentEvent>(){
                @Override
                public void componentSelected(ComponentEvent ce) {
                    // do your processing here                          

                }

            });
于 2012-12-06T22:01:57.467 回答
0

在 Java 中,函数不能像在 Javascript 中那样存在于类之外。因此,当您需要在运行时提供函数实现时,不幸的是,您必须将该函数包装在一个类中并传递该类的一个实例。

您使用反射的解决方案将起作用(我假设),但它不是在 Java 中执行此操作的首选方法,因为过去的编译时错误现在将成为运行时错误。

于 2012-12-06T22:52:11.857 回答