Відповідно до опису MVP Мартіна Фаулера ( http://martinfowler.com/eaaDev/uiArchs.html )
Про перегляд частини MVC Фаулер говорить:
Перший елемент Potel полягає в тому, щоб подати трактування як структуру віджетів, віджетів, які відповідають елементам управління формами та елементами управління та видалити будь-яке розділення перегляду / контролера. Вид MVP - це структура цих віджетів. Він не містить поведінки, яка описує, як віджети реагують на взаємодію користувачів .
(Сміливий акцент міна)
Потім ведучий:
Активна реакція на користувач діє в окремому об’єкті презентатора. Основні обробники жестів користувачів все ще існують у віджетах, але ці обробники просто передають контроль ведучому .
Потім ведучий вирішує, як реагувати на подію. Потель обговорює цю взаємодію насамперед з точки зору дій над моделлю, які вона робить за допомогою команд і виділень. Тут слід підкреслити підхід упаковки всіх редагувань до команди в команді - це забезпечує хорошу основу для відміни / повторення поведінки.
(Знову жирний наголос мій)
Отже, відповідно до вказівок Фоулера, ваш погляд не повинен відповідати за будь-яку поведінку у відповідь на подію кнопки; що включає створення екземпляра UserInfo
. Відповідальність за рішення щодо створення об'єкта належить методу Presenter, на який пересилається подія інтерфейсу користувача.
Однак можна також стверджувати, що обробник подій кнопки «Перегляд» також не повинен нести відповідальність за передачу вмісту вашого textView
, оскільки перегляд повинен просто пересилати подію кнопки у Презентатор і більше нічого.
Для MVP для перегляду прийнято реалізувати інтерфейс, який ведучий може використовувати, щоб збирати дані безпосередньо з подання (при цьому переконуючись, що ведучий все ще є агностичним для самого представлення). Так як UserInfo є простим POJO, це може бути справедливо для виду , щоб виставити геттер для UserInfo якій ведучий може забрати Фрон View через інтерфейс.
// The view would implement IView
public interface IView {
public UserInfo GetUserInfo();
}
// Presenter
public class AddUserPresenter {
private IView addUserView;
public void SetView(IView view) {
addUserView = view
}
public void onSomethingClicked() {
UserInfo userInfo = addUserView.GetUserInfo();
// etc.
}
}
Чим це відрізняється від UserInfo
прямого перегляду у подання за допомогою обробника подій? Основна відмінність полягає в тому, що ведучий все ще несе відповідальність за логіку, яка спричиняє створення UserInfo
об'єкта. тобто подія дійшла до Ведучого до створення UserInfo
, що дозволяє Ведучому приймати рішення.
Уявіть собі сценарій, коли у вас була логіка ведучого, коли ви не хотіли, UserInfo
щоб це створювалося на основі певного стану в області перегляду. Наприклад, якщо користувач не поставив прапорець у вікні перегляду або у вас була перевірка перевірки щодо якогось поля, яке потрібно додати в UserInfo, яке не вдалося - ваш презентатор може містити додаткову перевірку перед викликом GetUserInfo
- тобто
private boolean IsUsernameValid() {
String username = addUserView.GetUsername();
return (username != null && !username.isEmpty());
}
public void onSomethingClicked() {
if (IsUsernameValid()) {
UserInfo userInfo = addUserView.GetUserInfo();
// etc.
}
}
Ця логіка залишається всередині ведучого, і її не потрібно додавати у вигляд. Якщо вигляд відповідав за виклик, GetUserInfo()
то він також відповідав би за будь-яку логіку, пов'язану з його використанням; саме цього намагається уникати модель MVP.
Отже, хоча створений метод, який UserInfo
фізично може існувати в класі View, його ніколи не викликають із класу View, а лише з Presenter.
Звичайно, якщо створення UserInfo
кінців вимагає додаткових перевірок вмісту віджетів введення користувачем (наприклад, перетворення рядків, валідація тощо), тоді було б краще викрити окремі пристрої для отримання цих речей, так що перевірка / перетворення рядків може зайняти місце в Presenter - і тоді ведучий створює ваш UserInfo
.
Загалом, ваша основна мета, що стосується розмежування між Presenter / View, - це гарантувати, що вам ніколи не потрібно писати логіку у поданні. Якщо вам if
з будь-якої причини потрібно буде додати заяву (навіть якщо це if
заява про стан властивості віджета - перевірка порожнього текстового поля або булева грамота), це належить до презентатора.
onSomethingClicked()
, тож коли користувач натискає "щось", Перегляд дзвонитьpresenter.onSomethingClicked()
? Або мої методи презентації повинні бути названі як передбачені дії, в моєму випадкуaddUser()
?