29 апреля я читал мастер-класс по веб-разработке на GWT с использованием фреймворка mvp4g, на конференции Application Developer Days 2011. Предоставляю вам слайды (видео должно быть позже).
Слайды
План
- Введение. Краткая история и примеры использования GWT.
- Краткое описание концепций GWT
- JSNI
- Code Splitting
- MVP, RMVP, EventBus
- Deferred Binding
- Dependency Injection
- Remote Services
- mvp4g
- Чем помогает, отличия и достоинства
- Система аннотаций
- Реализация RMVP, EventBus
- History,
#!
- Мультимодульность
- Замечания
- Компоненты в GWT
UiBinder
, стандартные компоненты- Разработка каастомных компонентов
- Наша разработка Layouting-системы
- Работа с не-Java Server-Side API
- i18n в GWT
- Заключение. Ссылки на примеры
Ссылки со слайдов
- Слайды в PDF
- Кратко о GWT
- Концепции GWT
- mvp4g
- UI компоненты
- Layouting
- Non-Java API
- i18n
- Заключение
Вопросы
Во время презентации задавали вопросы, из которых я выделил самые важные:
Для каких сайтов подходит GWT?
По текущему состоянию, значительное расширение функциональности стандартных компонентов GWT вручную или добавление новых компонентов практически неизбежно ведёт к потере сразу нескольких достоинств GWT — кроссбраузерности и системы переопределения стилей: эти компоненты придётся отлаживать и верстать в различных браузерах самостоятельно.
Поэтому, самое очевидное применение GWT — сайты, где удобство пользователя достигается засчёт существующей компонентной базы и _не_изощрённого дизайном интерфейса (например, подобные Google Groups).
Это больше прикладные сайты, чем красивые. У таких сайтов часто вся функциональность происходит на одной странице, а не на нескольких. Нельзя сказать, что всё обратное — невозможно: возможно, и примером служит наш сайт, но всё это стоит намного больших трудов, чем использование стандартных компонентов и подходов. Однако, при всём при этом, для других UI-фреймворков упомянутое верно даже в большей степени, чем для GWT (то есть с использованием Apache Wicket сложнее сделать сложный красивый сайт, чем с использованием GWT).
Как работать с дизайнерами и верстальщиками при разработке сайта на GWT?
Дизайнерам надо дать установку либо на подавляющее использование стандартных компонентов/лэйаутов GWT в дизайне, либо на кропотливую разработку собственной библиотеки виджетов.
В первом случае вёрстка может даже не понадобиться (дизайн на страницы смогут наложить GWT-разработчики), во втором случае сдизайненную библиотеку виджетов верстальщикам придётся верстать кроссбраузерно, при этом верстальщиков придётся (очень желательно) учить лэйаутам GWT, системе CSS-стилей в GWT, концепциям виджето-ориентированного декларативного UI и структуре gwt.xml
.
Как более худший вариает, верстальщики могут верстать виджеты в HTML (но всё равно, каждый виджет по отдельности), а GWT-разработчики “накладывать” эту вёрстку на виджеты, уже в стиле GWT. Но это, и правда, худший вариант.
Как связаны понятия модулей в GWT и mvp4g?
На практике модуль в GWT — это чаще либо отдельная библиотека, либо веб-приложение целиком, либо его крупная часть. Модуль в mvp4g — это более атомарное понятие, например один модуль mvp4g полностью отвечает за работу с пользователями, второй модуль — за работу с новостями, третий — за работу с компаниями. При этом модуль mvp4g подразумевает одну шину событий для модуля, один HistoryConverter
и несколько презентеров и вьюх внутри. См. тж. демонстрацию Layouting (в процессе).
То есть в модуль mvp4g рекомендуется выделять работу с одним типом сущностей, в котором шина событий будет отвечать за действия с этим типом сущностей.
В этом есть огромное преимущество, потому что модули mvp4g можно загружать асинхронно (Code Splitting) — если пользователь не работает с какой-либо сущностью, эта часть JavaScript-кода даже не будет загружена в его браузер.
Как устроена система навигации в фреймворке mvp4g?
Из ответа на предыдущий вопрос сделаем вывод — поскольку в модуль mvp4g рекомендуется выделять работу с одним типом сущностей и такой модуль имеет один HistoryConverter
, предпочтительнее строить систему навигации по той же логике сущность -> действие
, например:
user/edit?56 // или user/edit/56, mvp4g позволяет это
user/show?56 // или user/show/56
user/friends?56 // или user/friends/56
user/list
company/edit?72 // или company/edit/72
company/show?72 // или company/show/72
company/employee?72 // или company/employee/72
company/list
Можно строить систему на URL вида user/56/edit
, принимая в HistoryConverter id
сущности и действие и в зависимости от действия вызывать соответствующее событие.
Это всё рекомендации, mvp4g на данный момент никак не ограничивает разработчика в разбиении кода на модули или способах формирования URL.
Концепция MVP подразумевает лёгкое тестирование. Тестируем ли мы UI и как тестируется mvp4g?
На данный момент мы тестируем UI вручную (тестеры ходят по сайту и проверяют функциональность). Фреймворк mvp4g позволяет использовать JUnit точно так же, как и для GWT — то есть никак не ограничивает. Вы всё также можете тестировать Presenter
как обычный класс, для моков можно использовать библиотеку mockito. Кроме того, каждый Presenter
имеет методы setView
и setEventBus
, поэтому вы можете инжектить mock-view и mock-eventbus используя GIN (обсуждение здесь).
Практического опыта в таком тестировании у нас нет, возможно кто-то опишется в комментариях по этому поводу.