2013-09-29 133 views
0

我在评估是否CDI事件可能对我的新应用程序有意义。到目前为止,我一直使用MVP体系结构,其中View仅具有UI元素,并将它们公开在公共getter中,而Presenter注册会单击它们上的侦听器。MVP - 注册点击监听器或使用CDI事件?

我来到CDI Events左右,想直接点击View类中的点击事件,并且在我的Presenters中只有observe这些事件。

你能告诉我哪种方法更好吗?或者你为什么总体上选择了另一种方法?

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活动

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(); 
    } 
} 

(本例使用Vaadin,但框架的选择不应该的问题,我一般问题)

要我的主要区别是:CDI不需要用户界面的getter,也不需要查看成员变量e发言人。缺点是,我需要为每个要触发的事件创建一个额外的事件类。

回答

3

那么,一个事件对象将是一种方式。另一个简单的方法就是使用一个限定符和你想观察的字符串值。

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

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

这对你的工作等价吗?

否则,这是一个相当不错的模式。尼斯方式保持您的应用程序解耦。

+0

原来,我正在寻找。 – membersound

5

就我个人而言,我不使用CDI事件将视图中的事件发送给其演示者。演示者和视图之间可以直接相互引用,这意味着与直接调用方法相比,CDI事件只会导致额外的代码和性能开销。当您想要解耦您的代码时,CDI事件非常有用,例如,它们适用于跨视图通信。作为一个方面说明,我倾向于将所有com.vaadin导入远离演示者,在您的情况下,这意味着该视图将实现ClickListener,并且演示者将具有诸如loginButtonClicked()这样的方法 - 当ClickEvent发生时,视图会调用该方法。这样我就可以在不影响演示者的情况下更改视图的实现。如果你认为这是一种好的或不好的做法,这可能是品味的问题。通常,这种方法的辩护是让演示者清理视图实现特定的技术使我们能够重复使用演示者,即使在用其他技术实现视图时也是如此,但我认为这颇具学术性。我得到的好处是,在为演示者进行单元测试时,我不需要模拟Vaadin组件。

+0

这是一个非常有趣的方法!到目前为止,我总是试图让主持人的参考脱离视图,因为总的来说,视图应该只知道UI,而不是关于模型或视图。但是你写的东西,特别是关于UI的实现,是非常有意义的! – membersound

+0

在某些情况下,您不希望演示者直接引用视图实现(例如,如果您针对同一视图有多个不同的实现,例如桌面和移动实现),那么您应该抽象视图主持人在界面后面的参考。 –

+0

如何修改视图中的组件(例如基于表单中的用户输入启用/禁用按钮)。你会做视图本身的用户输入验证和禁用吗?因为:如果您从演示者执行这些操作,则会产生循环依赖关系:该视图具有对演示者的引用,以便在单击按钮时调用其方法;并且演示者参考访问按钮组件的视图。 – membersound