Глава 7. Архитектура
Document-ViewРанее рассматривалось приложение, основанное на диалоге. Такое приложение типично для визуального программирования . Однако для
Visual C++ такие приложения не являются основными. В Visual C++ модель визуального программирования получила дальнейшее развитие в виде архитектуры приложения Document-View . Средство AppWizard позволяет создавать приложения, основанные на документах : приложения с однодокументным интерфейсом ( SDI - Single Document Interface) и приложения с многодокументным интерфейсом ( MDI - Multiple Document Interface). Они и являются основными для Visual C++.Созданное в
Visual C++ приложение функционирует как набор взаимодействующих объектов. Этот набор не случаен и выбирается не только программистом. В Visual C++ эти объекты организованы в систему со вполне четкой архитектурой Document-View.Правильно организованный пользовательский интерфейс должен обеспечивать первостепенную роль пользователя, отводя именно ему функции инициации и управления действиями приложения.
Самым подходящим для реализации такого требования является интерфейс, сфокусированный на данных. Суть его в том, что пользователь, работая с приложением, не начинает очередное действие с поиска команд, программ и другого инструментария. Прежде всего он должен видеть перед собой нужные данные, которые в свою очередь автоматически сопровождаются необходимыми для работы с ними командами и инструментарием.Особая роль здесь принадлежит разновидности данных, называемой документом . Это метафора : документ совсем не обязательно текст или таблица. Он может быть картой, мелодией, числом - любым объектом.
Приложение должно строиться так, чтобы, видя один или несколько документов, пользователь сосредоточил внимание на них самих, а не на средствах работы с документами. Архитектура Document-View как раз предоставляет, а в некотором смысле навязывает программисту систему объектов, позволяющих строить приложения, сфокусированные на данных, а точнее - на документах.
Документы и облики
Центральными объектами в архитектуре приложения являются один или несколько объектов, называемых документами. Они ориентированы на хранение информации и имеют хорошо развитые методы загрузки, сохранения и управления данными. Документы создаются как объекты классов, производных от класса CDocument библиотеки MFC.
Каждый документ сопровождается одним или несколькими объектами, которые называются обликами
. Через облики происходит взаимодействие пользователя с документами. Облик является объектом, предназначенным для отображения документа на экране и распознавания команд пользователя по управлению документом. Для изменения документа облики используют методы документа.Облики создаются как объекты классов, производных от класса CView библиотеки классов MFC. Кроме класса CView , библиотека содержит ряд классов, производных от CView , которые также можно применять для создания своих классов обликов.
Если документ большой, то, как правило, облик отображает на экране часть документа и представляет пользователю возможность перемещать "взгляд" по документу.
Каждый облик должен быть сопоставлен некоторому документу. Один документ может иметь несколько обликов, и в таком случае они, как правило, обеспечивают различное представление документа на экране.
Создание документов и обликов
Так как документы и их облики являются одними из наиболее важных составляющих архитектуры Document-View, их создание выполняется каркасом приложения . Процесс создания довольно сложен, остановимся на наиболее существенных моментах.
Первый связан со специальными объектами - документными шаблонами (document template). Принадлежа классу CDocTemplate (класс "Документный шаблон") или производным от него классам, они задают описание наиболее существенной части архитектуры, включая описание наиболее существенной части архитектуры Document-View, включая описание класса документа, класса облика документа и класса окна-рамки документа. Документные шаблоны бывают двух видов : для однодокументного интерфейса (SDI) и для многодокументного интерфейса ( MDI).
Создание документа и связанных с ним объектов выполняется при открытии пользователем документа - существующего или нового. Это происходит в начале работы приложения, а также когда пользователь выбирает команды
Open и New в меню File.Создание начинается с выбора шаблона документа. В соответствии с описанным в шаблоне классом документа создается сам документ. Если шаблон задает
MDI-интерфейс, то каждый раз создается новый объект-документ. Если же шаблон задает SDI-интерфейс, новый объект создается только один раз, а при выборе пользователем команд Open и New производится только "обнуление" имеющегося объекта документа.Для инициализации созданного документа каркас приложения вызывает метод OnNewDocument при открытии нового документа, а при открытии уже имеющегося - OnOpenDocument . Оба метода принадлежат базовому классу CDocument . Они являются виртуальными, и поэтому, переопределив их, программист может задать необходимые действия по инициализации документа. Однако, эти методы и сами по себе выполняют ряд действий, связанных с инициализацией, - в частности, проверяют, что объект-документ пуст. Переопределенный метод заменяет метод базового класса, поэтому нужно предусмотреть вызов в нем метода базового класса. Остовы методов OnNewDocument и OnOpenDocument , созданные AppWizard, содержат такой вызов.
Для инициализации документа используется и конструктор документа (это тоже виртуальный метод. Однако, как говорилось выше, если шаблон задает SDI-интерфейс, то при повторном создании или открытии документа объект лишь "обнуляется", и конструктор, следовательно, не вызывается. Поэтому конструктор документа можно использовать для инициализации лишь в случае приложений с MDI-интерфейсом или для инициализации, которая будет важна для всех экземпляров.
После создания документа создается объект главное окно-рамка, который управляет главным Windows-окном приложения. Внутри этого окна располагаются окна-рамки документов. Объект окно-рамка документа создается главным окном-рамкой и служит для управления Windows-окном, внутри которого облик отображает содержимое документа. Окно-рамка документа как раз и создает объект-облик .
Если открывается уже существующий документ, каркас приложения вызывает метод
Serialize , который производит загрузку (а при закрытии документа - сохранение) документа из "среды постоянного хранения", которой чаще всего является диск.Заключительный этап создания документа и связанных с ним объектов - инициализация облика и отображение содержимого документа посредством этого облика.
Взаимодействие документов и обликов
Логически облики привязаны к документу. У классов
CDocument и CView есть механизмы для поддержания этой связи. Класс CDocument инкапсулирует список, хранящий все облики данного документа. С помощью методов этого класса облик добавляется и удаляется из списка, осуществляется просмотр списка и получение обликов.Метод класса
CView позволяет облику получить документ, за которым он закреплен :CDocument* GetDocument() const;
Этот метод очень важен
: без него облик не получит доступ к методам документа. Он возвращает константный указатель на документ, за которым закреплен облик. Если облик не закреплен ни за каким документом, возвращается NULL.Допустим, документ имеет несколько обликов, один из которых изменяет документ. Тогда остальные облики должны синхронизировать свое отображение с измененным содержанием этого документа. Такую синхронизацию обеспечивает метод
UpdateAllViews класса CDocument.Классы объектов-обликов должны быть устроены так, чтобы при получении сообщения
Update обрабатывающий их метод производил синхронизацию облика с документом. Обычно это означает синхронизацию данных облика и синхронизацию изображения в окне облика. Простейший вариант такой синхронизации дает метод OnUpdate класса CView . Он состоит в отправке объектом сообщения OnDraw самому себе. Если программист не предусмотрел своего метода обработки сообщения Update, то при получении этого сообщения облик выполняет метод OnUpdate базового класса CView .