0

I'm evaluating if CDI Events could make sense for my new application. So far I always worked with MVP architectures where the View only has the UI elements and exposes them in public getters, whereas the Presenter registers click listeners on them.

I came around CDI Events and thought about to fire the click events in the View classes directly, and simply only observe these events in my Presenters.

Could you tell me which approach is the better one? Or why would you in general chose one over the other approach?

MVP:

class LoginView {   
    private Button loginButton;

    public void getButton() {
        return loginButton;
    }
}


class LoginPresenter {
    @Inject
    private LoginView view;

    public LoginPresenter() {
        view.getButton.addClickListener(new ClickListener() {
            @Override
            public void buttonClick(ClickEvent event) {
                //perform the login business logic
            }
        });
    }
}

CDI Events:

class LoginView {   
    private Button loginButton;

    @Inject
    private Events<LoginEvent> events;

    public LoginView() {
        loginButton.addClickListener(new ClickListener() {
            @Override
            public void buttonClick(ClickEvent event) {
                events.fire(new LoginEvent("login"));
            }
        });
    }
}


class LoginPresenter {
    private void listenLogin(@Observes LoginEvent evt) {
        //perform the login business logic
    }
}

class LoginEvent extends EventObject {
    public LoginEvent(String source) {
        super();
    }
}

(this example uses Vaadin, but framework choice should not matter for my question in general)

To me the main difference is: CDI requires no getters for the UI and no view member variables in the Presenter. On the downside, I need to create an extra event class for every event that is to be fired.

4

2 回答 2

5

就个人而言,我不使用 CDI 事件将事件从视图发送到其演示者。演示者和视图相互直接引用,这意味着与直接方法调用相比,CDI 事件只会导致额外的开销(代码和性能)。当您想要解耦代码时,CDI 事件很有用,例如,它们非常适合跨视图通信。

作为旁注,我倾向于将所有 com.vaadin 导入远离演示者,这在您的情况下意味着视图将实现 ClickListener 并且演示者将具有诸如 loginButtonClicked() 之类的方法-视图将调用ClickEvent 发生时的那个方法。这样我可以在不影响演示者的情况下更改视图的实现。如果您认为这是一个好的或坏的做法,这可能是一个品味问题。通常,这种方法的防御是保持演示者清洁视图实现特定技术允许我们重用演示者,即使在使用另一种技术实现视图时,但我认为这是相当学术的。我得到的好处是我在为我的演示者进行单元测试时不需要模拟 Vaadin 组件。

于 2013-09-30T07:23:29.167 回答
3

好吧,事件对象将是一种方式。另一种方法是简单地将限定符与您要观察的字符串值一起使用。

@Inject
@Presenter("loginView")
private Event<Object> viewEvent;

public void onLoginView(@Observes @Presenter("loginView") Object viewEvent) {
    ... whatever has to happen
}

这对你同样有效吗?

否则,这是一个非常好的模式。保持应用程序解耦的好方法。

于 2013-09-29T21:52:28.227 回答