Как стать автором
Обновить

Martin Fowler — GUI Architectures. Часть 3

Время на прочтение5 мин
Количество просмотров9K
Часть третья. Для минимизации количества отсебятины, текст переводится очень близко по смыслу, вследствие чего перевод приобретает «рубленные» черты. Тем, кто решил прочитать, следует читать осторожно, ибо прочитанное может нанести вред внутреннему чувству эстетики.

Предыдущая часть здесь. Оригинал статьи — здесь.


Модель приложения VisualWorks


Как я уже говорил выше, шаблон MVC в языке Smalltalk 80 оказался очень успешным и обладал набором отличных свойств и некоторых недостатков. По ходу развития Smalltalk в 80-х и 90-х годах все это вылилось в значительные изменения классической модели MVC. По правде говоря, из MVC исчезло то, что определяет его имя — разделение представления от контроллера.

Остались аспекты, которые очевидно работали в MVC — это разделенное представление (Separated Presentation) и синхронизация через обозреватель (Observer Syncronization). Эти аспекты для многих людей являлись ключевым элементом MVC и продолжили свое развитие вместе с платформой Smalltalk.

Smalltalk также пошел по нескольким различным веткам развития. Появилось несколько платформ Smalltalk, с единым определением языка, но с разными библиотеками. Некоторые из них стали использовать «родные» для операционной системы элементы управления в стиле, описанном в «Формах и элементах».

Smalltalk был разработан в фирме Xerox Parc, после чего она выделила продажи и развитие платформы в новую фирму ParcPlace. Систему ParcPlace Smalltalk переименовали в VisualWorks и сделали ее кроссплатформенной. Еще задолго до появления Java вы могли взять программу, написанную на Smalltalk в операционной системе Windows и тут же запустить ее в ОС Solaris. Для этого VisualWorks не использовала «родные» элементы управления и хранила GUI полностью внутри себя.

Я закончил свое обсуждение MVC выделением нескольких проблемных мест — в частности, как работать с логикой представления и состоянием представления. VisualWorks решила эти проблемы созданием новой особой конструкции, т.н. моделью приложения (Application Model) — конструкцией, близкой по смыслу с моделью представления (Presentation Model). Идея создать нечто, похожее на (Presentation Model) не являлась новаторством — еще в Smalltalk 80 на нее был очень похож code browser, однако VisualWorks явно выделила модель приложения в свой каркас.

Ключем этой идеи является превращение свойств в объекты (объекты-свойства). Рассмотрим пример — объект Person с двумя свойствами — именем Name и адресом Adress. Эти свойства могут быть полями класса или чем-то другим. В Java, чтобы доступиться до свойства объекта, мы пишем temp = aPerson.getName() и aPerson.setName("martin"). В C# — temp = aPerson.name и aPerson.name = "martin".

Объект-свойство возвращает объект-обертку текущего значением свойства. Таким образом, если в VisualWorks мы запросим имя Name у Person, мы получим объект-обертку Name. А само имя Name получается через прямой запрос к значению объекта-обертки. Обеспечить доступ к имени Name можно вот так: temp = aPerson name value и aPerson name value: 'martin'

Этот подход позволяет немного легче делать отображение данных между элементами управления и моделью. Нужно просто сказать элементу, какое сообщение ему нужно послать в соответствующее свойство. Тем самым элемент будет знать, как доступиться до значения свойства через код value и value:. В VisualWorks объекты-свойства так же позволяют настраивать обозреватель через сообщение вида onChangeSend: aMessage to: anObserver.

К слову, в VisualWorks нет объекта под названием объект-свойство (Property Object). Вместо него существуют несколько других классов, которые поддерживают протокол value/value:/onChangeSend:. Самый простой из них — класс ValueHolder. Этот класс просто содержит значение свойства. Более сложный и актуальный для данного обсуждения класс — AspectAdaptor. Он позволяет объекту-свойству обернуть свойство другого (!) объекта. Тем самым, появляется возможность сделать класс PersonUI и определить в нем объект-свойство для объекта Person. Код будет примерно таким:

adaptor := AspectAdaptor subject: person
adaptor forAspect: #name
adaptor onChangeSend: #redisplay to: self


Посмотрим, как модель приложения ляжет в наш текущий пример:



Рисунок 9: Диаграмма классов для модели приложения VisualWorks в нашем примере

Основное различие между моделью приложения и классическим MVC состоит в том, что теперь у нас существует промежуточный класс (модель приложения) между доменной моделью и элементом управления. Элементы управления теперь не доступаются до доменных объектов напрямую — их моделью теперь является модель приложения. Они так же разбиты на представления и контроллеры, но пока вы не создаете новые элементы управления, это разбиение не играет большой роли.

Назначение аспектов для элементов управления происходит обычным образом в редакторе UI. Аспект соответствует методу модели приложения, который возвращает объект-свойство.



Рисунок 10: Диаграмма последовательностей, на которой показано, как обновление текущего значения обновляет текст отклонения

На рисунке 10 показано, как работает обновление данных. Когда я меняю значение в текстовом поле, это поле обновляет значение в объекте-свойстве принадлежащем модели приложения. После чего следует обновление значения в нижележащем доменном объекте.

Потом вступает в дело обозреватель. Нам нужно настроить систему так, чтобы обновление текущего свойства заставило объект «замер» сказать всем о том, что он изменился. Мы делаем это через специальный вызов в определении текущего значения — в частности, он нужен для того, чтобы оповестить о том, что аспект отклонения изменился. Аспектный адаптер (aspect adaptor) очень легко настраивается для слежения за объектом «замер». Когда нужно, он ловит сообщение об обновлении и переадресует его к текстовому полю. После этого, используя тот же аспектный адаптер, текстовое поле получает новое значение.

Использование модели приложения и объектов-свойств помогает нам справиться с обновлениями данных малой кровью. Они так же поддерживают «мелкозернистую» синхронизацию (и я не думаю, что это хорошо).

Модели приложения позволяют разделить специфичные для UI поведение и состояние от доменной логики. Ранее я упомянул одну проблему, о том, где правильно хранить значение для текущего выбранного из списка объекта. Она может быть решена введением специального вида аспектного адаптера, который будет оборачивать список доменных объектов, а так же хранить текущий выбранный из них.

Ограничением данного подхода является то, что при более сложном поведении вам придется создавать специальные элементы управления и объекты-свойства. Например, в указанных выше примерах не затрагивается назначение цвета текстовому полю отклонения. Используя разделение моделей приложения и домена можно ввести правильное поведение, но для создания связей между аспектными адаптерами и элементами управления все же придется написать несколько новых классов. Часто это является слишком сложным, поэтому мы можем ослабить требования и позволить модели приложения получить доступ к элементам управления напрямую. Смотрим рисунок 11.



Рисунок 11. Модель приложения обновляет цвет текстового поля путем прямого доступа к нему

Прямой доступ к элементам управления не совсем то, что имелось в виду при описании модели представления (Presentation Model). Именно поэтому модель приложения не является моделью представления (Presentation Model). Необходимость доступаться напрямую к элементам управления воспринимается многими как маленький «грязный прием», позволивший развить подход Модель-Представление-Контроллер.

Подведем итоги модели представления.

  • Модель представления последовала за MVC через развитие разделенного представления (Separated Presentation) и синхронизации через обозреватель (Observer Syncronization).
  • Модель представления представляет из себя промежуточный класс, где описывается логика представления и состояние представления. Модель приложения является частичным развитием модели представления (Presentation Model).
  • Элементы управления больше не обозревают доменные объекты. Вместо них они обозревают модель приложения.
  • Широкое использование объектов-свойств помогает разработчику соединять различные слои приложения и поддерживать синхронизацию через обозреватели.
  • Модель приложения имеет непосредственный доступ к элементам управления. Это поведение не является поведением по-умолчанию, но активно используется в сложных сценариях.


Следующая часть здесь.
Теги:
Хабы:
Всего голосов 12: ↑12 и ↓0+12
Комментарии4

Публикации

Истории

Ближайшие события