2012-05-13 3 views
1

MVP pattern предполагает, что View подвергает методы Presenter. Например, в View мы можем написать:MVP узор. Как уменьшить код, повторяющийся?

public HasClickhandlers getButton() { 
    return myBtn; 
} 

и доступ к этому методу от ведущего, как

view.getButton().addclickhanlder() ... 

Но когда я строй моего приложения в этом стиле, у меня есть много ненужного код. Например, я хочу создать TablesView и TablesPresenter (я решаю, что TablesPresenter и TablesView - это минимальная сущность (минимальный модуль), которая не может быть разделена на более мелкие презентаторы и представления и не может быть более сложной). Затем, когда я создаю TablesView, я хочу добавить в это представление другой пользовательский компонент - MyCustomTable. И внутри MyCustomTable положить MyCustomHeader, внутри MyCustomHeader положить MyCustomFilter и т. Д. (Эта последовательность может быть намного длиннее) ... Так что проблема в том, когда я хочу получить доступ от Presenter до введенного текста (пользователем) внутри MyCustomFilter, мне нужно разоблачить метод на MyCustomFilter:

//inside MyCustomFilter 
public String getFilterText() { 
    return textBox.getText(); 
} 

затем в виджете, который содержит MyCustomFilter - то есть в MyCustomHeader мне нужно выставить этот метод:

//inside MyCustomHeader 
public String getFilterText() { 
    return myCustomFilter.getFilterText(); 
} 

после этого, внутри MyCustomTable мне нужно выставить этот метод:

//inside MyCustomTable 
public String getFilterText() { 
    return myCustomHeader.getFilterText(); 
} 

После этого мне нужно выставить getFilterText() метод внутри TablesView (который содержит MyCustomTable) и после всех этих операций мой ведущий может получить доступ к тексту внутри MyCustomFilter .. А когда-то эта последовательность более длиннее. Итак, как решить эту проблему? Может быть, я не понимаю некоторых вещей о MVP?

+0

Переформулируйте свой вопрос. Это хаотично и содержит слишком много деталей. – dzendras

ответ

1

Одним из способов решения этой проблемы было бы использование интерфейсов. Благодаря этому вы можете выставить представление о своих компонентах без создания плотной связи между представлением и презентатором.

Что-то вдоль этих линий:

public interface CustomFilter { 
    String getFilterText(); 
    // other methods that might be accessed from your presenter 
} 

public class MyCustomFilter implements CustomFilter { 

    @Override 
    public String getFilterText() { 
     return textBox.getText(); 
    } 
} 

Вы можете сделать то же самое для других componenents:

CustomHeader:

public interface CustomHeader { 
    CustomFilter getFilter(); 
    // or String getFilterText() 
    // other methods that might be accessed from your presenter 
} 

public class MyCustomHeader implements CustomHeader { 

    @Override 
    public CustomFilter getFilter() { 
     return myCustomFilter; 
    } 
} 

Настроенная:

public interface CustomTable { 
    CustomHeader getHeader(); 
    // or Sring getFilterText(); 
    // other methods that might be accessed from your presenter 
} 

public class MyCustomTable implements CustomTable { 

    @Override 
    public CustomHeader getHeader() { 
     return myCustomHeader; 
    } 
} 

Y ou может решить, хотите ли вы показывать только в каждом интерфейсе только интерфейс String или весь клиентский компонент. Если вы подвергаете весь интерфейс можно нарушать law of demeter, имея звонки, как это в вашем ВЕДУЩИЙ:

getView().getTable().getHeader().getFilter().getFilterText(). 

Вероятно, лучшим решением было бы определить строк в ваших интерфейсов, которые Делегат звонки по иерархии в вашей CustomFilter интерфейс: getView().getTable().getFilterText(); или even getView().getFilterText().

Другие преимущества использования интерфейсов заключаются в том, что вы можете легко имитировать их для модульного тестирования ваших презентаторов и даже просмотра компонентов по отдельности, и вы можете легко создать переключатель между различными реализациями компонентов вашего интерфейса (например, тот, который оптимизирован для смартфоны и т. д.), ничего не меняя в ваших докладчиках

2

Там нет причин, ваша точка зрения не может вернуть вида на одном из его компонентов, но вы должны думать в терминах компонентизаций: что сломает инкапсуляцию, ваше мнение, то подвергает его внутренности.

Кроме того, имейте в виду, что одним из наиболее важных преимуществ MVP в GWT является то, что вы можете легко высмеять свои взгляды и выполнить единичный тест ваших докладчиков без вялого GWTTestCase. Есть компромиссы, чтобы сделать ваш код легко проверяемым/макетируемым.

+0

спасибо, поэтому вы предлагаете мне выставить метод, возвращающий весь пользовательский компонент (как вы написали - целые 'view'), например:' public MyCustomHeader getHeader() 'вместо возврата public String getFilterText() {return myCustomHeader.getFilterText ()}? – MyTitle

+0

Ну, вы можете разоблачить свой '' MyCustomHeader'', но тогда вы создадите плотную связь между вашим компонентом пользовательского интерфейса MyCustomHeader' и вашим '' Presenter'', и вам, вероятно, придется издеваться над всем компонентом 'MyCustomHeader'' для использования Тесты JUnit. Кроме того, если позже вы решите иметь другую реализацию своего «MyCustomHeader», скажем, планшеты или мобильные устройства, вы столкнетесь с проблемами. Вместо этого вы можете создать интерфейс для своего пользовательского интерфейса '' MyCustomHeader'', который предоставляет все функции, которые вы хотите вызвать из своего '' Presenter''. –

+0

@ Ümit, спасибо. Так что подведите итоги. Во-первых: внутри моего представления и других нетривиальных пользовательских компонентов пользовательского интерфейса (которые содержат другие настраиваемые виджеты) мне нужно разоблачить методы, которые получают доступ ко всему содержащемуся компоненту, а не только к методам, которые получают доступ к методам сдерживаемых компонентов. Во-вторых: лучше использовать интерфейсы для всех пользовательских компонентов, а не их реализацию. – MyTitle

Смежные вопросы