GWT MVP с местами и мероприятиями - где модель?
Я пытаюсь познакомиться с шаблоном проектирования "Места и занятия" для разработки GWT, и до сих пор думаю, что у него большой потенциал. Мне особенно нравится то, как, когда вы начинаете думать о своем приложении с точки зрения "Мест", история браузера практически просто ложится вам на колени практически без лишних усилий.
Тем не менее, меня беспокоит только одно: все статьи и примеры кода, которые я видел до сих пор, затуманивают один (на мой взгляд, основной) аспект: часть "M" в "MVP", то есть модель!
Насколько я понимаю, в обычной архитектуре MVP Presenter хранит ссылку на модель и отвечает за ее обновление в соответствии с событиями пользовательского интерфейса или, соответственно, обновление пользовательского интерфейса в соответствии с изменениями модели.
Теперь, во всех статьях / примерах для "P&A" Видимости, кажется, занимают место докладчика, но в отличие от "обычных" докладчиков, они отбрасываются и (заново) создаются всякий раз, когда появляется новое место, поэтому они могут Не храните состояние клиента, иначе оно будет потеряно каждый раз. Создавать действия дешево, так что это не большая проблема, но я бы не хотел создавать модель сложного приложения снова и снова.
Все примеры довольно просты и не имеют большого количества состояний, и поэтому просто игнорируют аспект модели, но где в реальном сложном приложении будет храниться его состояние?
2 ответа
Я думаю, что нашел свой ответ. Кажется, что главная проблема заключается в том, что все простые примеры кода делают Activity выступающими в качестве докладчиков, как в:
public class NavigationActivity extends AbstractActivity implements NavigationView.Presenter {
private final ClientFactory clientFactory;
private final NavigationPlace place;
public NavigationActivity(ClientFactory clientFactory, NavigationPlace place) {
this.clientFactory = clientFactory;
this.place = place;
}
@Override
public void start(AcceptsOneWidget panel, EventBus eventBus) {
NavigationView navView = clientFactory.getNavigationView();
navView.setSearchTerm(place.getSearchTerm());
navView.setPresenter(this);
panel.setWidget(navView);
}
@Override
public void goTo(Place place) {
clientFactory.getPlaceController().goTo(place);
}
}
Теперь действия довольно недолговечны, тогда как типичный Presenter в "классическом" смысле имеет гораздо более длительный срок службы, чтобы поддерживать связь между моделью и пользовательским интерфейсом. Поэтому я реализовал отдельный Presenter с использованием стандартного шаблона проектирования MVP, и все, что делает Activity, выглядит примерно так:
public class NavigationActivity extends AbstractActivity {
private final ClientFactory clientFactory;
private final NavigationPlace place;
public NavigationActivity(ClientFactory clientFactory, NavigationPlace place) {
this.clientFactory = clientFactory;
this.place = place;
}
@Override
public void start(AcceptsOneWidget panel, EventBus eventBus) {
NavigationPresenter presenter = clientFactory.getNavigationPresenter();
presenter.setSearchTerm(place.getSearchTerm());
presenter.go(panel);
}
}
Таким образом, вместо того, чтобы Activity извлекала представление и действовала на нем как Presenter, она выбирает фактического Presenter, просто сообщает ему об изменении состояния клиента, вызванном Place, и сообщает ему, где отображать его информацию (то есть представление)., И Presenter теперь может свободно управлять представлением и моделью так, как ему нравится - этот способ работает намного лучше (по крайней мере, с учетом того, что я имею в виду для приложения, над которым я работаю), чем примеры кода, которые я нашел так далеко.
Вы правы, почти всегда ведущий является единственным, кто держит модель и управляет ее временем жизни. Модель из предыдущих версий GWT просто представляла собой DTO (и продолжает оставаться) POJO, который создается десериализатором GWT при возврате методов RPC или создается Presenters и заполняется данными пользовательского интерфейса UIHandlers и отправляется на сервер.
Я предпринял усилия, чтобы сохранить время жизни моделей в рамках времени действия "Деятельности" и избежать сохранения состояния вне действий. (Однако у меня есть одноэтапное глобальное состояние, поддерживаемое для использования из любого места приложения.) Я думаю, это то, что инженеры GWT MVP предполагали, что это произойдет - имеет смысл, когда, скажем, пользователь ушел из Места для связанных моделей с этим местом также, чтобы избавиться (и собрал). Создавайте модели, заполняйте их внутри действий и выполняйте сервисные вызовы, чтобы обновить сервер перед тем, как уйти (или вызвать какой-то элемент управления на странице), и позволить им выполнять это задание - это то, чем я занимался до настоящего времени.
Более крупный проект, в котором я участвовал, столкнулся с довольно большим количеством проблем с памятью браузера, и все они были связаны с объектами, которые связаны с другим (в данный момент не просматриваемым) местом, находящимся в памяти. Было трудно отследить и удалить ссылки на эти объекты, и, поскольку пользователь отошел от экрана - вопрос "почему мои старые экранные объекты все еще находятся в памяти?" Часто возникал и впоследствии исправлялся. Вот почему, заранее, я решил сохранить срок жизни Модели в рамках срока действия Деятельности в моем текущем домашнем проекте.
Если у вас есть модели, которые охватывают (которые заполнены / доступны) нескольким действиям (как в случае, если у вас есть боковые панели и виджеты master/container), возможно, потребуется некоторая модернизация моделей, если у вас есть примеры, я постараюсь помочь,