Предыдущая часть здесь. Оригинал статьи — здесь.
Модель приложения 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).
- Элементы управления больше не обозревают доменные объекты. Вместо них они обозревают модель приложения.
- Широкое использование объектов-свойств помогает разработчику соединять различные слои приложения и поддерживать синхронизацию через обозреватели.
- Модель приложения имеет непосредственный доступ к элементам управления. Это поведение не является поведением по-умолчанию, но активно используется в сложных сценариях.
Следующая часть здесь.

