Предыдущая серия была тут - http://18delphi.blogspot.com/2013/08/mvc.html
Теперь будем продолжать реализацию прецедента "работа с документом".
У нас остались нереализованные требования:
6. Печать и предварительный просмотр всего документа.
7. Печать и предварительны просмотр выделенных участков документа.
8. Переход по ссылкам. Ссылки бывают - внутренние (внутри данного прецедента) и внешние (между различными прецедентами).
9. Логирование функций работы с документом.
10. Экспорт всего документа в определённые форматы.
11. Экспорт выделенного участка текста в определённые форматы.
Начнём с "Печать и предварительный просмотр всего документа".
Пусть собственно ФУНКЦИОНАЛ печати и предварительного просмотра - УЖЕ "как-то" реализован. А именно ОТДЕЛЬНЫМ классом:
- это пока только "набросок".
Теперь посмотрим - как этот ПРОЕКТНЫЙ класс связан с прецедентом "работа с документом".
Напомню как выглядит прецедент "просмотр документа":
С точки зрения визуализации:
С точки зрения данных:
Куда "всунуть" TDocumentPrintMachine?
Стоп!
Тут я забыл про один вопрос - "как данные связываются с визуализацией?"
Сейчас мы рассмотрим этот вопрос.
Пока почитайте вот это - http://www.delphinotes.ru/2013/01/delphi.html#more
Там - ОЧЕНЬ правильные вещи про "базовую форму" и "базовый фрейм" написаны.
СВОЯ "базовая форма" и "базовый фрейм". Николай - там - ОЧЕНЬ верно это описал.
Будем считать, что TForm => TvcmForm, TFrame => TvcmViewArea.
А теперь посмотрим, как преображается наша модель:
- тут мы видим "данные" и "представление" ОДНОВРЕМЕННО.
(Ещё раз напоминаю! "Геометрию" и Owner/Parent - мы рассмотрим - позже. Потому, что ТУТ - не ВСЁ ТАК ПРОСТО. Например есть TPanel а есть TTabView. ;-) "Активные зоны" могут себя ПО-РАЗНОМУ вести :-))
А где они ("данные" и "представление") в итоге "встречаются"? Сейчас мы это - рассмотрим:
Модель (и фреймворк) дают нам следующее:
Идея понятна? По-моему - она - ОЧЕВИДНА :-)
И ЭТО ВСЁ - генерируется с модели. Спросите меня - "где модель" и "как оно генерируется"? Я расскажу - чуть позже...
Теперь вернёмся к требованиям и ответственностям.
......
Для начала посмотрим вот сюда:
Предположим, что ответственность "Печать и предварительный просмотр всего документа" реализует объект TDocumentTextViewArea. Ну то есть - печатать и просматривать документ позволяют ДВЕ "активных зоны" - DocumentTextViewArea и DocumentAnnotationViewArea.
Для начала - определим пользовательские "точки входа", а именно - операции "Печать" и "Предварительный просмотр".
Предположим, что операции определяет мета-директива operation.
Это аналог procedure, но с ФИКСИРОВАНОЙ сигнатурой и возможностью ПУБЛИКАЦИИ в toolbar'е и всевозможных меню. А также - operation может УПРАВЛЯТЬ видимостью и доступностью этих "пунктов меню". Но об этом - позже.
(<<operation>> это кстати один из СТЕРЕОТИПОВ нашей мета-модели UML, но про UML - тоже позже)
"Ноги" operation - растут из TAction на самом деле :-) (это для любителей Delphi).
продолжим наверное в следующей статье...
.................
to be continued....
Теперь будем продолжать реализацию прецедента "работа с документом".
У нас остались нереализованные требования:
6. Печать и предварительный просмотр всего документа.
7. Печать и предварительны просмотр выделенных участков документа.
8. Переход по ссылкам. Ссылки бывают - внутренние (внутри данного прецедента) и внешние (между различными прецедентами).
9. Логирование функций работы с документом.
10. Экспорт всего документа в определённые форматы.
11. Экспорт выделенного участка текста в определённые форматы.
Начнём с "Печать и предварительный просмотр всего документа".
Пусть собственно ФУНКЦИОНАЛ печати и предварительного просмотра - УЖЕ "как-то" реализован. А именно ОТДЕЛЬНЫМ классом:
TDocumentPrintMachine = class procedure Preview; procedure Print; end;//TDocumentPrintMachine
- это пока только "набросок".
Теперь посмотрим - как этот ПРОЕКТНЫЙ класс связан с прецедентом "работа с документом".
Напомню как выглядит прецедент "просмотр документа":
С точки зрения визуализации:
type TDocumentForm = class(TForm) TDocumentTextViewArea = class(TFrame) Text : TDocumentView; end;//TDocumentTextViewArea DocumentTextViewArea : TDocumentTextViewArea; TListViewArea = class(TFrame) List : TListView; end;//TListViewArea DocumentContents: DocumentContentsViewArea: TDocumentContentsViewArea = class(TFrame) DocumentStructureViewArea: TDocumentStructureViewArea = class(TFrame) Tree : TTreeView; end;//TDocumentStructureViewArea DocumentPicturesViewArea: TListViewArea; end;//TDocumentContentsViewArea DocumentIncomingLinksViewArea: TListViewArea; DocumentOutgoingLinksViewArea: TListViewArea; DocumentAnnotationViewArea: TDocumentTextViewArea; end;//TDocumentForm
С точки зрения данных:
type TDocumentUseCaseData = class(TUseCaseData) TDocumentTextViewAreaData = class(TViewAreaData) property Text: TDocument; end;//TDocumentTextViewAreaData property DocumentText: TDocumentTextViewAreaData; TListViewAreaData = class(TViewAreaData) property List : TList; end;//TListViewAreaData property DocumentContents: TDocumentContentsViewAreaData = class(TViewAreaData) property DocumentStructure: TDocumentStructureViewAreaData = class(TViewAreaData) property DocumentStructure : TTree; end;//TDocumentStructureViewAreaData property DocumentPictures: TListViewAreaData; end;//TDocumentContentsViewAreaData property DocumentIncomingLinks: TListViewAreaData; property DocumentOutgoingLinks: TListViewAreaData; property DocumentAnnotation: TDocumentTextViewAreaData; end;//TDocumentUseCaseData
Куда "всунуть" TDocumentPrintMachine?
Стоп!
Тут я забыл про один вопрос - "как данные связываются с визуализацией?"
Сейчас мы рассмотрим этот вопрос.
Пока почитайте вот это - http://www.delphinotes.ru/2013/01/delphi.html#more
Там - ОЧЕНЬ правильные вещи про "базовую форму" и "базовый фрейм" написаны.
СВОЯ "базовая форма" и "базовый фрейм". Николай - там - ОЧЕНЬ верно это описал.
Будем считать, что TForm => TvcmForm, TFrame => TvcmViewArea.
А теперь посмотрим, как преображается наша модель:
type TDocumentForm = class(TvcmForm) f_DocumentData : TDocumentUseCaseData; TDocumentTextViewArea = class(TvcmViewArea) f_TextData : TDocumentTextViewAreaData; Text : TDocumentView; end;//TDocumentTextViewArea DocumentTextViewArea : TDocumentTextViewArea; TListViewArea = class(TvcmViewArea) f_List : TListViewAreaData; List : TListView; end;//TListViewArea DocumentContents: DocumentContentsViewArea: TDocumentContentsViewArea = class(TvcmViewArea) f_Contents : TDocumentContentsViewAreaData; DocumentStructureViewArea: TDocumentStructureViewArea = class(TvcmViewArea) f_Structure : TDocumentStructureViewAreaData; Tree : TTreeView; end;//TDocumentStructureViewArea DocumentPicturesViewArea: TListViewArea; end;//TDocumentContentsViewArea DocumentIncomingLinksViewArea: TListViewArea; DocumentOutgoingLinksViewArea: TListViewArea; DocumentAnnotationViewArea: TDocumentTextViewArea; end;//TDocumentForm
- тут мы видим "данные" и "представление" ОДНОВРЕМЕННО.
(Ещё раз напоминаю! "Геометрию" и Owner/Parent - мы рассмотрим - позже. Потому, что ТУТ - не ВСЁ ТАК ПРОСТО. Например есть TPanel а есть TTabView. ;-) "Активные зоны" могут себя ПО-РАЗНОМУ вести :-))
А где они ("данные" и "представление") в итоге "встречаются"? Сейчас мы это - рассмотрим:
Модель (и фреймворк) дают нам следующее:
type TDocumentForm = class(TvcmForm) f_DocumentData : TDocumentUseCaseData; TDocumentTextViewArea = class(TvcmViewArea) f_TextData : TDocumentTextViewAreaData; Text : TDocumentView; procedure GotData(aData : TDocumentTextViewAreaData); begin f_TextData := aData; Text.Text := aData.Text; end; end;//TDocumentTextViewArea DocumentTextViewArea : TDocumentTextViewArea; TListViewArea = class(TvcmViewArea) f_List : TListViewAreaData; List : TListView; procedure GotData(aData : TListViewAreaData); begin f_List := aData; List.List := aData.List; end; end;//TListViewArea DocumentContents: DocumentContentsViewArea: TDocumentContentsViewArea = class(TvcmViewArea) f_Contents : TDocumentContentsViewAreaData; DocumentStructureViewArea: TDocumentStructureViewArea = class(TvcmViewArea) f_Structure : TDocumentStructureViewAreaData; Tree : TTreeView; procedure GotData(aData : TDocumentStructureViewAreaData); begin f_Structure := aData; Tree.Tree := aData.Tree; end; end;//TDocumentStructureViewArea DocumentPicturesViewArea: TListViewArea; procedure GotData(aData : TDocumentContentsViewAreaData); begin f_Contents := aData; DocumentStructureViewArea.GotData(aData.DocumentStructure); DocumentPicturesViewArea.GotData(aData.DocumentPictures); end; end;//TDocumentContentsViewArea DocumentIncomingLinksViewArea: TListViewArea; DocumentOutgoingLinksViewArea: TListViewArea; DocumentAnnotationViewArea: TDocumentTextViewArea; procedure GotData(aData : TDocumentUseCaseData); begin f_DocumentData := aData; DocumentTextViewArea.GotData(aData.DocumentText); DocumentContentsViewArea.GotData(aData.DocumentContents); DocumentIncomingLinksViewArea.GotData(aData.DocumentIncomingLinks); DocumentOutgoingLinksViewArea.GotData(aData.DocumentOutgoingLinks); DocumentAnnotationViewArea.GotData(aData.DocumentAnnotation); end; end;//TDocumentForm
Идея понятна? По-моему - она - ОЧЕВИДНА :-)
И ЭТО ВСЁ - генерируется с модели. Спросите меня - "где модель" и "как оно генерируется"? Я расскажу - чуть позже...
Теперь вернёмся к требованиям и ответственностям.
......
Для начала посмотрим вот сюда:
TDocumentTextViewArea = class(TvcmViewArea) Text : TDocumentView; end;//TDocumentTextViewArea DocumentTextViewArea : TDocumentTextViewArea; ... DocumentAnnotationViewArea: TDocumentTextViewArea; ...
Предположим, что ответственность "Печать и предварительный просмотр всего документа" реализует объект TDocumentTextViewArea. Ну то есть - печатать и просматривать документ позволяют ДВЕ "активных зоны" - DocumentTextViewArea и DocumentAnnotationViewArea.
Для начала - определим пользовательские "точки входа", а именно - операции "Печать" и "Предварительный просмотр".
Предположим, что операции определяет мета-директива operation.
Это аналог procedure, но с ФИКСИРОВАНОЙ сигнатурой и возможностью ПУБЛИКАЦИИ в toolbar'е и всевозможных меню. А также - operation может УПРАВЛЯТЬ видимостью и доступностью этих "пунктов меню". Но об этом - позже.
(<<operation>> это кстати один из СТЕРЕОТИПОВ нашей мета-модели UML, но про UML - тоже позже)
"Ноги" operation - растут из TAction на самом деле :-) (это для любителей Delphi).
продолжим наверное в следующей статье...
.................
to be continued....
Кстати, мы на практике очень часто такое используем - перед отображением формы, например, с табличными данными, заполняется объект, который определяет поведение формы. Например - возможность редактирование записей, либо выбор одной записи, либо выбор нескольких записей (результат выбора возвращается в объекте). Либо много чего ещё может быть (например, по какой таблице будет форма строится).
ОтветитьУдалитьИ этот объект передаётся с конструктором формы (или фреймы).
Я про это тоже хотел написать, но лето, дети, разленился ((
"Кстати, мы на практике очень часто такое используем - перед отображением формы, например, с табличными данными, заполняется объект, который определяет поведение формы"
Удалить;-) ВЕРЮ!!!
Я ведь САМ - IUnknown ПРИДУМАЛ :-) Я ведь САМ - НИЧЕГО не придумал :-)
"Я про это тоже хотел написать, но лето, дети, разленился" - я САМ - многое ЧЕГО НЕ НАПИСАЛ :)
Но я ВСЕХ - приглашаю в СОАВТОРЫ, :-) если тема "про MVC" - "прёт" :-)
Самоё клёвое было бы - "я рассказываю на пальцах.. Вы это пишите :-) Все лавры - вам..." :-) А мне - удовлетворение :-)
Поставьте кстати хотя бы "интересно"... А то все читают - и пишут "вау - круто"... А другие говорят - "у тебя, что ни одного читателя?" :-)
УдалитьИ все - комплексуют быть первыми :-)
Сам - поставил - "забавно"...
ОтветитьУдалить