Java GUI 的观察者模式 - 无需 typeof 即可区分不同的事件

Java observer pattern for a GUI - distinguish between different events without typeof

我有一个简单的 Controller 对象,它实现了 Observer(即它是观察者),它监听来自扩展 ObservableMouse 对象的事件(即它是被观察者)。

所以一个 Mouse 对象中可以有多个事件,例如左键单击、向上滚动等

现在 Controller class 实现了每次上述任何事件发生时都会调用的所需方法:

@Override
public void update(Observable o, Object arg)
{
    // Handle mouse event
}

所以我在决定如何处理 时遇到困难的是 arg 参数(我正在处理的这种情况非常简单,因此 o 参数不是问题)。不使用typeof区分不同鼠标事件的好方法是什么?

即我应该在 Mouse 观察者 class 的 notifyObservers(Object arg) 方法中输入什么参数?

阅读评论似乎您正在使用 SWT -- SWT 已经通过 observer/observable 回调实现了事件处理程序。

你在这里试图做的是在SWT已经实现的观察者模式之上再实现一层观察者模式,这没有多大意义。但是如果你真的想练习它,你可能想要制作几个内部私有 classes 来处理不同的事件,例如:

/**
* Controller.java
*/
import java.util.Observable;
import java.util.Observer;

public class Controller
{
/**
 * The controller's inner classes are to be notified of mouse events.
 */
public Controller(Mouse mouse)
{
    mouse.addObserver(new LeftClickObserver());
    mouse.addObserver(new ScrollUpObserver());
}

private class LeftClickObserver implements Observer
{

    @Override
    public void update(Observable o, Object arg)
    {
        // TODO Handle left clicks

    }

    // Other left click logic here
    // ...
}

private class ScrollUpObserver implements Observer
{

    @Override
    public void update(Observable o, Object arg)
    {
        // TODO Handle scroll up

    }

    // Other scroll up logic here
    // ...
}
}

然后就可以在Mouseclass中适当的事件中调用notifyObservers(Object arg)方法来触发对Controller的回调了。

但是如前所述,您应该改为使用现有的 SWT 库来处理事件,然后将控制器中事件处理的实现与视图分开(正如您已经尝试做的那样)。这是一个如何执行此操作的简单示例(假设您在鼠标 class 的某处初始化了控制器,并在控制器 class 中使用了适当的方法):

final Button button = new Button(shell, SWT.PUSH);

button.addSelectionListener(new SelectionListener() {

  public void widgetSelected(SelectionEvent event) {
    controller.handleWidgetSelectedEvent(event); // controller decides what to do...
  }

  public void widgetDefaultSelected(SelectionEvent event) {
    controller.handleWidgetDefaultSelectedEvent(event); // controller decides what to do...
  }
});

请注意,在 MVC 模式的某些版本中,View 处理大部分事件,and/or 模型;所以真的,这取决于你的项目。可能直接在视图中处理事件是最简单的策略。