Какова ваша рекомендация по архитектуре приложений GWT? MVC, MVP или пользовательское решение для обмена сообщениями?
Я только что начал новый проект GWT для клиента, и мне интересно услышать опыт людей с различными архитектурами GWT MVC. В недавнем проекте я использовал GXT MVC, а также пользовательское решение для обмена сообщениями (на основе Appcelerator MQ). GXT MVC работал нормально, но он казался излишним для GWT, и было трудно работать с историей браузера. Я слышал о PureMVC и GWTiger, но никогда не использовали их. Наше обычное решение MQ работало довольно хорошо, но было сложно тестировать компоненты с помощью JUnit.
Кроме того, я слышал, что Google Wave (приложение GWT) написано с использованием шаблона Model-View-Presenter. A образец приложения MVP был недавно опубликован, но, глядя на код, он не кажется интуитивным.
Если вы строите новое приложение GWT, какую архитектуру вы бы использовали? Каковы плюсы и минусы по вашему выбору?
Спасибо,
Matt
Ответы
Ответ 1
Стоит отметить, что Google окончательно выписал учебник для проектирования с использованием архитектуры mvp. Он разъясняет многие элементы из google i/o talk, перечисленных выше. Возьмите looK: https://developers.google.com/web-toolkit/articles/mvp-architecture
Ответ 2
Я рад, что этот вопрос задан, потому что GWT desperatley нужен рельсоподобный способ структурирования приложения. Простой подход, основанный на передовой практике, которая будет работать на 90% всех случаев использования и обеспечивает возможность суперпростой проверки.
В последние годы я использую свою собственную реализацию MVP с очень пассивным взглядом, который порабощает себя, что говорит ему ведущий.
Мое решение состояло из следующего:
- интерфейс для виджета, определяющий методы управления внешним видом.
- класс реализации, который может быть составным или использовать внешнюю библиотеку виджетов
- центральный презентатор для экрана, на котором размещены N представлений, состоящих из M виджетов
- центральная модель на экране, которая содержит данные, связанные с текущим визуальным внешним видом.
- общие классы-слушатели, такие как "SourcesAddEvents [CustomerDTO]" (редактор не любит настоящие символы для java-дженериков здесь, поэтому я использовал скобки thoe), потому что в противном случае у вас будет много тех же интерфейсов, которые просто отличаются типом
Представления получают ссылку на презентатора в качестве параметра конструктора, поэтому они могут инициализировать свои события с помощью презентатора. Ведущий будет обрабатывать эти события и уведомлять о других виджетах/представлениях и также вызывать gwt-rpc, которые при успешном выполнении помещают его результат в модель. Модель имеет типичный механизм "Свойство [List [String]] names =....", который регистрируется ведущим, так что обновление модели по запросу gwt-rpc переходит ко всем представлениям/виджетам, которые заинтересованы.
С этой оценкой я получил очень легкую проверку с помощью EasyMock для своих AsynInterfaces. Я также получил возможность легко обмениваться реализацией виджета/виджета, потому что все, что мне пришлось переписать, это код, который уведомлял ведущего о каком-либо событии - независимо от основного виджета (Button, Links и т.д.).
Проблемы с моим подходом:
- Моя текущая реализация затрудняет синхронизацию значений данных между центральными моделями разных экранов. Предположим, у вас есть экран, на котором отображается набор категорий и другой экран, который позволяет добавлять/редактировать эти элементы. В настоящее время очень сложно распространять эти события изменений через границы экранов, потому что значения кэшируются в этих моделях, и трудно найти, загрязнены ли некоторые вещи (было бы легко в традиционном web1.0-html -dumb-terminal типа сценария с декларативным кэшированием на стороне сервера).
- Параметры конструктора представлений допускают сверхлегкое тестирование, но без сплошной рамки Dependency-Injection у вас будет некоторый UGLY factory/установочный код внутри "onModuleLoad()". В то время, когда я начал это, я не знал о Google GIN, поэтому, когда я реорганизую свое приложение, я буду использовать его, чтобы избавиться от этого шаблона. Интересным примером здесь является игра "HighLower" внутри GIN-Trunk.
- В первый раз я не получил право Истории, поэтому трудно перейти от одной части моего приложения к другому. Мой подход не осознает историю, которая является серьезным спадом.
Мои решения для этих проблем:
- Используйте GIN для удаления установочного шаблона, который трудно поддерживать
- При переходе с Gwt-Ext на GXT используйте свою инфраструктуру MVC как EventBus для подключения/отсоединения модульных экранов, чтобы избежать проблем с кешированием и синхронизацией.
- Подумайте о какой-то "Place" -Abstraction, такой как Ray Ryan, описанной в его разговоре в I/O 09, которая соединяет разницу между GXT-MVC и GWT-Hitory подходом
- Используйте MVP для виджетов, чтобы изолировать доступ к данным.
Резюме:
Я не думаю, что можно использовать один подход "MVP" для всего приложения. Одна из них, безусловно, нуждается в истории для приложений-навигации, таких как GXT-MVC для подключения/отсоединения экранов и MVP, чтобы упростить тестирование доступа к данным для виджетов.
Поэтому я предлагаю многоуровневый подход, который объединяет эти три элемента, поскольку я считаю, что решение one-event-mvp-system не будет работать. Навигация/привязка экрана/доступ к данным - это три отдельные проблемы, и я буду реорганизовывать свое приложение (переход на GXT) в следующие месяцы, чтобы использовать все три фреймворка событий для каждой проблемы отдельно (лучший инструмент для работы). Все три элемента не должны знать друг о друге. Я знаю, что мое решение применимо только к GXT-проектам.
При написании больших приложений GWT я чувствую, что мне нужно изобретать что-то вроде Spring -MVC на клиенте, что действительно отстойно, потому что требуется много времени и сил мозга, чтобы выплескивать что-то элегантное, как Spring MVC. GWT нуждается в платформе приложений гораздо больше, чем те небольшие JS-оптимизации, с которыми так сложно работать компилятор-ребята.
Ответ 3
Вот недавняя презентация Google IO на архитектура вашего приложения GWT.
Enjoy.
-JP
Ответ 4
Если вы заинтересованы в использовании архитектуры MVP, вы можете взглянуть на GWTP: http://code.google.com/p/gwt-platform/. Это открытая MVP-среда с открытым исходным кодом, над которой я работаю, которая поддерживает множество приятных функций GWT, включая разделение кода и управление историей, с простым API на основе аннотаций. Это совсем недавно, но уже используется в ряде проектов.
Ответ 5
Вы должны посмотреть Портлеты GWT. Мы разработали GWT Portlets Framework, работая над большим приложением для портала HR, и теперь он является бесплатным и открытым исходным кодом. На веб-сайте GWT Portlets (размещенном в коде Google):
Модель программирования несколько похожа на запись портлетов JSR168 для портала портала (Liferay, JBoss Portal и т.д.). "Портал" - это ваше приложение, построенное с использованием инфраструктуры почтовых портов GWT в качестве библиотеки. Функциональность приложения разрабатывается как слабосвязанные портлеты, каждая с дополнительным сервером DataProvider на стороне сервера.
Каждый портлет знает, как экрнализировать свое состояние в сериализуемый подкласс PortletFactory (шаблон momento/DTO/ factory), что делает возможной функциональность:
- Операции CRUD обрабатываются одним GWT RPC для всех портлетов
- Макет портлетов на "странице" может быть представлен как дерево WidgetFactory (интерфейс, реализованный PortletFactory).
- Деревья WidgetFactory могут быть сериализованы и упорядочены в/из XML на сервере, для хранения макетов GUI (или "страниц" ) в файлах страниц XML.
Другие важные функции структуры перечислены ниже:
- Страницы могут быть отредактированы в браузере во время выполнения (разработчиками и/или пользователями) с помощью редактора компоновки фреймов
- Портлеты расположены абсолютно так, чтобы использовать области прокрутки
- Портлеты настраиваются, указывать, когда они заняты загрузкой для автоматического отображения "загружаемого счетчика" и могут быть максимальными.
- Тематические виджеты, включая стилизованное диалоговое окно, замену кнопок в стиле CSS, небольшие кнопки и меню с шаблоном HTML
Портлеты GWT реализованы в Java-коде и не обертывают внешние библиотеки Javascript. Он не накладывает никакой рамки на стороне сервера (например, Spring или J2EE), но предназначен для эффективной работы в сочетании с такими фреймворками.