Глава 14. Типовые решения, предназначенные для представления данных в Web 349
• Объекты, не имеющие визуального интерфейса, гораздо легче тестировать, чем
объекты с интерфейсом. Отделение представления от модели позволяет легко про-
тестировать всю логику домена, не прибегая к таким "ужасным" вещам, как сред-
ства написания сценариев для поддержки графического интерфейса пользователя.
Ключевым моментом в отделении представления от модели является направление
зависимостей: представление зависит от модели, но модель не зависит от представления.
Программисты, занимающиеся разработкой модели, вообще не должны быть осведомле-
ны о том, какое представление будет использоваться. Это существенно облегчает разра-
ботку модели и одновременно упрощает последующее добавление новых представлений.
Кроме того, это означает, что изменение представления не требует изменения модели.
Данный принцип тесно связан с распространенной проблемой. При использовании
толстого клиента с множеством диалоговых окон на экране могут одновременно нахо-
диться несколько представлений одной и той же модели. Если пользователь внесет из-
менения в модель посредством одного представления, эти изменения должны быть от-
ражены и во всех остальных представлениях. Чтобы это было возможным при отсутствии
двунаправленной зависимости, необходимо реализовать типовое решение наблюдатель
(Observer) [20] с использованием метода распространения событий (event propagation)
или в виде типового решения слушатель (Listener). В этом случае представление будет
выполнять роль "наблюдателя" за моделью: как только модель будет изменена, представ-
ление генерирует соответствующее событие и все остальные представления обновляют
свое содержимое.
Отделение контроллера от представления не играет такой важной роли, как предыду-
щий тип разделения. Действительно, по иронии судьбы практически во всех версиях
Smalltalk разделение на контроллер и представление не проводилось. Классическим при-
мером необходимости подобного разделения является поддержка редактируемого и не-
редактируемого поведения. Этого можно достичь при наличии одного представления и
двух контроллеров (для двух вариантов использования), где контроллеры являются стра-
тегиями [20], используемыми представлением. Между тем на практике в большинстве
систем каждому представлению соответствует только один контроллер, поэтому разделе-
ние между ними не проводится. О данном решении вспомнили только при появлении
Web-интерфейсов, где отделение контроллера от представления оказалось чрезвычайно
полезным.
Тот факт, что в большинстве инфраструктур пользовательских интерфейсов не про-
водилось разделение на представление и контроллер, привел к множеству неверных тол-
кований типового решения модель-представление—контроллер. Да, наличие модели и
представления очевидно, но где же контроллер? Многие решили, что контроллер нахо-
дится между моделью и представлением, как в контроллере приложения (Application
Controller, 397). Данное заблуждение еще более усугубил тот факт, что в обоих названиях
фигурирует слово "контроллер". Между тем, несмотря на все положительные качества
контроллера приложения, он ничем не похож на контроллер типового решения модель-
представление—контроллер.
Описанные принципы — это все, что требуется для понимания данного набора типо-
вых решений. Если же вам захочется еще немного покопаться в типовом решении мо-
дель-представление—контроллер, обратитесь к источнику [33] — там содержится лучшее
на данный момент описание этого типового решения.