MVP - зарегистрировать прослушиватель кликов или использовать события CDI?

Я оцениваю, могут ли события CDI иметь смысл для моего нового приложения. До сих пор я всегда работал с MVP архитектурами, где View имеет только элементы пользовательского интерфейса и предоставляет их в общедоступных геттерах, тогда как Presenter регистрирует для них прослушиватели щелчков.

Я пришел к CDI Events и подумал о том, чтобы запускать события щелчка в View классах напрямую, и просто observe эти события в моем Presenters.

Не могли бы вы сказать мне, какой подход лучше? Или почему вы вообще предпочли бы один подход другому?

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 не требует никаких геттеров для пользовательского интерфейса и никаких переменных-членов представления в презентаторе. С другой стороны, мне нужно создать дополнительный класс событий для каждого события, которое должно быть запущено.


person membersound    schedule 29.09.2013    source источник


Ответы (2)


Что ж, объект события был бы односторонним. Другой вариант - просто использовать квалификатор со строковым значением того, что вы хотите наблюдать.

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

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

Будет ли это работать для вас одинаково?

В остальном это довольно красивый узор. Хороший способ сохранить ваше приложение изолированным.

person John Ament    schedule 29.09.2013
comment
Это оказалось именно то, что я искал. - person membersound; 30.09.2013

Лично я не использую события CDI для отправки событий из представления его ведущему. Ведущий и представление имеют прямые ссылки друг на друга, что означает, что события CDI вызовут только дополнительные накладные расходы (как в коде, так и в производительности), чем при выполнении прямых вызовов методов. События CDI полезны, когда вы хотите разделить свой код, например, они отлично подходят для межвидового взаимодействия.

В качестве побочного примечания я стараюсь держать весь мой импорт com.vaadin подальше от ведущего, что в вашем случае означало бы, что представление будет реализовывать ClickListener, а ведущий будет иметь такой метод, как loginButtonClicked () - представление будет вызывать этот метод при возникновении ClickEvent. Таким образом, я мог изменить реализацию представления, не затрагивая ведущего. Вероятно, это дело вкуса, считаете ли вы это хорошей или плохой практикой. Обычно защита этого подхода заключается в том, что сохранение ведущего в чистоте от конкретных технологий реализации представления позволяет нам повторно использовать докладчика даже при реализации представления с помощью другой технологии, но я думаю, что это довольно академично. Преимущество, которое я получаю, заключается в том, что мне не нужно издеваться над компонентами Vaadin при выполнении модульных тестов для моего докладчика.

person Kim L    schedule 30.09.2013
comment
Это очень интересный подход! До сих пор я всегда старался не допускать ссылки на докладчика в представление, поскольку в целом говорится, что представление должно знать только о пользовательском интерфейсе, а не о модели или представлении. Но то, что вы написали, особенно в отношении реализации пользовательского интерфейса, имеет большой смысл! - person membersound; 30.09.2013
comment
В некоторых случаях вы не хотите, чтобы у докладчика была прямая ссылка на реализацию представления (например, если у вас есть несколько разных реализаций для одного и того же представления, например настольная и мобильная реализация), тогда вам следует абстрагироваться от ссылки на представление. в презентаторе за интерфейсом. - person Kim L; 30.09.2013
comment
А как насчет случаев, когда вам нужно изменить компоненты в представлении (например, включить / отключить кнопку на основе ввода данных пользователем в форме). Вы бы тогда выполняли проверку и отключение пользовательского ввода в самом представлении? Потому что: если вы выполняете эти действия от ведущего, у вас будет циклическая зависимость: представление имеет ссылку на ведущего для вызова его методов при нажатии кнопки; и ведущий имеет ссылку на представление для доступа к компоненту кнопки. - person membersound; 30.09.2013
comment
Вы можете сказать, что описанная вами модель - это модель-представление-модель представления (MVVM)? - person membersound; 30.09.2013