PureMVC Gestalt
Фреймворк PureMVC преследует очень узкую цель. Она в том, чтобы помочь вам разделить интересы кода вашего приложения на три отдельных уровня: Модель (Model), Представление (View) и Контроллер (Controller).
Для создания масштабируемых и легко поддерживаемых приложений высоким приоритетом являются разделение интересов, а так же герметичность и направление связей между уровнями MVC
В данной реализации классического мета-паттерна MVC эти три уровня приложения управляются тремя синглтонами (классами, для которых возможно существование одного и только одного экземпляра), называемыми просто: Модель (Model), Представление (View) и Контроллер (Controller). Все вместе они называются Базовыми классами (Core actors).
Четвертый синглтон, Фасад (Facade), упрощает разработку, предоставляя единый интерфейс для сообщения с Базовыми классами.
Оказали влияние
PureMVC — это фреймворк, основанный на шаблонах проектирования. Он появился из насущной необходимости проектирования высокопроизводительных RIA-клиентов. Сейчас он уже портирован на другие языки и платформы, включая серверные среды.
Хотя интерпретация и реализация имеют свои особенности для каждой поддерживаемой PureMVC платформы, используемые паттерны описаны в известной книге ‘Gang of Four’: Design Patterns: Elements of Reusable Object-Oriented Software (GoF) (ISBN 0-201-63361-2)
The Clean Architecture описывает основные общие правила построения архитектуры приложения. Как сделать разработку тестируемой, удобной, понятной, а части системы взаимозаменяемыми. Оригинал статьи
При создании программных систем использование принципов SOLID способствует созданию такой системы, которую будет легко поддерживать и расширять в течение долгого времени. Принципы SOLID — это руководства, которые также могут применяться во время работы над существующим программным обеспечением для его улучшения, например, для удаления «дурно пахнущего кода». Wiki
InversifyJS — это IoC-контейнер. Мы можем использовать IoC-контейнер для внедрения значений в компоненты, не передавая их явно через каждый компонент и не используя контекст. InversifyJS поддерживает два вида внедрений:
- внедрение через constructor
- внедрение через свойство
Однако LeanES фреймворк не является эталонной реализацией спецификации PureMVC на языке JavaScript. Наша команда портировала спецификацию PureMVC фреймворка в LeanES в качестве отдельного слоя. Несомненно это самый важный слой LeanES, т.к. предоставляет программисту основные идиомы, с помощью которых можно построить любое приложение.
Однако нужно отметить несколько отличий от спецификации PureMVC:
- Добавлены короткие алиасы для основных методов в акторах PureMVC (Model, View, Controller, Mediator, Proxy, Command) для написания более компактного кода. Эталонные названия методов сохранены для обратной совместимости или для легкой миграции программиста с другой платформы или языка программирования, где он уже использовал PureMVC.
- Классы SimpleCommand и MacroCommand объединены в один класс Command, по существу с сохранением всей функциональности это MacroCommand, но если переопределить в унаследованном классе метод execute() - это будет просто SimpleCommand.
- Добавлены отсутствующие методы для безопасного удаления созданных сингелтонов в случае, когда мультитон удаляется. В оригинальной спецификации предусмотрено только создание мультитонов, но не их удаление.
- Интегрированы дополнительные сущности и методы для работы с ними через Фасад в рамках концепции "Clean Architecture" by Robert C. Martin (Uncle Bob). Эти сущности Кейс (Case), Сьюит (Suite) и Адаптер (Adapter) только расширяют уровни абстракций в составе PureMVC с сохранением обратной совместимости с эталонной спецификацией.
- В базовые классы ядра (Model, View, Controller, Facade) интегрирована библиотека InversifyJS.
Не смотря на то, что Фасад по существу реализует возможность для инъекции
зависимостей через вызов метода
this.facade.retrieveProxy()
илиthis.facade.retrieveMediator()
, однако в этом случае конкретные классы Медиатора, Команды и Прокси становятся зависимы от самого Фасада - что является примером антипатерна Сервис-локатор (Service Locator). Поэтому в состав LeanES на уровне PureMVC интегрирована библиотека InversifyJS, которая предоставляет возможность описания в классах Медиаторов, Команд и Прокси а так же в Кейсов, Сьюитов и Адаптеров "классической" инъекции зависимостей, т.е. через конструктор или через проперти. Подробнее об этом можно прочитать в разделе "Инверсия зависимости".
Наша команда выражает благодарность создателям PureMVC за возможность портирования их решения в наш фреймворк LeanES. Ниже приводим сноску из оригинальной документации PureMVC:
PureMVC является бесплатным фреймворком с открытым кодом от Futurescale, Inc.
Copyright © 2006-09. Некоторые права защищены. Использование ограничено лицензией
Creative Commons 3.0. Документация, обучающие материалы и примеры кода с сайта
Futurescale's предоставляются «как есть», без всяких гарантий и включая, но,
не ограничиваясь ими, подразумеваемые гарантии пригодности для целей, или гарантий
ненарушения прав. Implementation Idioms & Best Practices.doc
Вся нижеследующая документация для сущностей PureMVC в большей степени базируется на оригинальной документации PureMVC. Однако примеры кода и отличительные особенности портированной версии описываются в нижеследующей документации в соответствие с реальной имплементацией в LeanES фремворке, в том числе и мплементация всех базовых классов PureMVC.
Модель и Прокси (Model & Proxies)
Модель просто кэширует именованные ссылки к Прокси. Код Прокси манипулирует моделью данных, связываясь с удаленными сервисами, если нужно сохранить или запросить данные. Таким образом, Модель данных изолирована от контроллеров и представления. Это приводит к переносимому коду Модели.
Представление и Медиаторы (View & Mediators)
Представление в первую очередь кэширует именованные ссылки на Медиаторы. Код Медиатора обслуживает компонент(ы) Представления, добавляя к ним Слушателей событий и от их имени отправляя и получая оповещения к и от остальной системы, при этом непосредственно управляя их состоянием. Это отделяет определение Вида от управляющей им логики.
Контроллер и Команды (Controller & Commands)
Контроллер кеширует ссылки на классы Команд, создавая экземпляры класса команды в тот момент, когда возникает необходимость выполнения этой команды и уничтожая после выполнения.
Команды могут запрашивать Прокси и взаимодействовать с ними, отправлять Оповещения, выполнять другие Команды, и часто используются для дирижирования сложными, охватывающими всю или почти всю систему действиями, такими, как запуск или остановка приложения. Это альмаматер бизнес-логики вашего приложения.
Фасад и Ядро (Facade & Core)
Фасад (Facade), еще один синглтон, инициализирует Базовые классы (Модель, Представление и Контроллер) и предоставляет единую точку доступа ко всем их публичным методам.
Расширяя Фасад, ваше приложение получает в распоряжение весь функционал Базовых классов без необходимости их импорта и прямой работы с ними. Вы реализуете конкретный Фасад в своем приложении только один раз, и это делается очень просто.
Прокси, Медиаторы и Команды могут использовать конкретный Фасад вашего приложения для того, чтобы получать доступ и связываться друг с другом.
Наблюдатели и Оповещения (Observers & Notifications)
PureMVC-приложения могут выполняться в различных средах, так что фреймворк реализует схему оповещений Наблюдатель (Observer) для сообщения между Базовыми классами MVC и другими частями системы в манере слабого связывания.
Вам не нужно беспокоиться о деталях реализации Наблюдателя/Оповещения (Observer/Notification) в PureMVC; это внутренняя часть фреймворка. Вам нужно только использовать простой метод для отправки Оповещений от Прокси, Медиаторов, Команд и Фасада, который даже не требует создавать экземпляр Оповещения.
Оповещения можно использовать для запуска Команд
Команды связаны с именами Оповещений в вашем конкретном Фасаде и автоматически выполняются Контроллером, когда отправляются назначенные им Оповещения. Команды обычно дирижируют сложным взаимодействием между интересами Представления и Модели, при этом зная о них настолько мало, насколько это возможно.
Медиаторы отправляют и получают Оповещения, а так же заявляют о заинтересованности в них
При регистрации в Представлении Медиаторы опрашиваются на предмет их заинтересованности в Оповещениях, для чего вызывается метод listNotifications, и должны возвращать массив имен Оповещений, в которых они заинтересованы.
Позже, когда кто-то в системе отправляет одноименное Оповещение, заинтересованные Медиаторы будут оповещены через вызов их метода handleNotification, которому будет передана ссылка на Оповещение.
Прокси отправляют, но не получают Оповещений
Прокси могут отправлять Оповещения по различным поводам. Например, Прокси для удаленного сервиса может оповестить систему о том, что он получил результат с сервера. Или другой Прокси может оповестить систему о том, что изменились его данные.
Для Прокси слушать Оповещения — это слишком сильное связывание с уровнями Вида и Контроллера.
Эти уровни обязаны слушать Оповещения от Прокси, так как их функция заключается в визуальном представлении и обеспечении взаимодействия пользователя с данными Модели, за которые отвечают Прокси.
Тем не менее, уровни Вида и Контроллера должны иметь возможность изменений, не влияющих на уровень Модели данных.
Например, административное приложение и связанное с ним пользовательское приложение могут иметь общие классы уровня Модели. Если отличаются только сценарии использования, то эти отличия можно реализовать за счет различных комбинаций Представления и Контроллера, работающих с одной и той же Моделью.