Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Frame vs DataModule

10
25 марта 2005 года
Freeman
3.2K / / 06.03.2004
Предупреждаю сразу - тема флудерская. Суть проста: DataModule - suxx, Frame - rulez. Вопрос, можно сказать, идеологический или даже политический. ;)

Пару лет назад мой питерский друг в дискуссии сказал, что DataModule, как правило, применяют неправильно. Создать в проекте один модуль данных и напихать в него компонентов, строго говоря - нарушение основ ООП. Причина проста - модуль данных существует только в одном экземпляре и порой бывает очень трудно (читай - невозможно) создать несколько экземпляров окон, пользующихся компонентами из модуля данных. Возникают дурацкие идеи "клонирования компонентов" и тому подобные бредни.

Мой друг тогда сказал: модулей данных в проекте должно быть много - по одному на каждую сущность. Я слова запомнил, но на практике применить их пришлось только недавно.

При разработке очередного проекта прикинул, что если располагать компоненты на одной большой SDI-форме с "вкладочным" интерфейсом, на ней места живого не будет. Нужен контейнер, позволяющий прятать часть невидимых компонентов, переключаясь между группами, объединенными общей функциональностью. И оказалось, что такой контейнер в VCL есть! Зовется фреймом. Сразу вспомнились слова друга про сущности.

Короче, при использовании фреймов предлагается размещать видимые и невидимые компоненты вместе. Логическая группировка и разбиение на модули в проекте при этом ведется по сущностям: одна сущность - один фрейм.

Найденное решение было претворено на практике. Получилось просто великолепно, со всех точек зрения. Весь прикладной код работы с сущностью находится в одном модуле. Главная форма несет на себе только объект подключения к БД, занимается чтением конфигурации и отработкой нажатий на кнопки панели инструментов. Последнее у меня было сделано через дополнительно объявленные виртуальные методы в наследниках фрейма.

Хотелось бы подискутировать на эту тему, поискать достоинства и недостатки предложенного решения. По функциональности проект у меня был не очень большой, по объему - тоже.
10
25 марта 2005 года
Freeman
3.2K / / 06.03.2004
Цитата:
Originally posted by smartsoft
Вопрос, можно сказать, идеологический или даже политический. ;)


Вспомнил вот еще что. Был в моей практике чистый случай применения модуля данных.

В компонентах SAX (которые совсем не suxx) для записи XML используется один компонент, а для чтения - целая куча. Мне же хотелось реализовать чтение и запись двумя функциями. Чтобы не мудрить и не создавать компоненты для чтения в рантайме, создал модуль данных, накидал, что нужно и использовал внутри функции. Разумеется, экземпляр модуля данных внутри функции создавался и уничтожался.

На мой взгляд, это единственный чистый случай использования модуля данных. Во всех остальных его с гораздо большим успехом можно заменить фреймом.

259
25 марта 2005 года
AlexandrVSmirno
1.4K / / 03.12.2004
Цитата:
Originally posted by smartsoft
Вспомнил вот еще что. Был в моей практике чистый случай применения модуля данных.

В компонентах SAX (которые совсем не suxx) для записи XML используется один компонент, а для чтения - целая куча. Мне же хотелось реализовать чтение и запись двумя функциями. Чтобы не мудрить и не создавать компоненты для чтения в рантайме, создал модуль данных, накидал, что нужно и использовал внутри функции. Разумеется, экземпляр модуля данных внутри функции создавался и уничтожался.

На мой взгляд, это единственный чистый случай использования модуля данных. Во всех остальных его с гораздо большим успехом можно заменить фреймом.



Сначала про TDataModule: (извиняюсь за цитирование help-a, я думаюВы его конечно же читали)

TDataModule centralizes the handling of nonvisual components in an application

Use a TDataModule object in an application to provide a location for centralized handling of nonvisual components. Typically these are data access components, such as TSQLDataSet, and TSQLConnection. DataModules are not limited to data access components, they can also contain other nonvisual components, such as TTimer, TOpenDialog, TImageList, or TOleContainer).


Т.Е. если верить фирме Борланд, то это типичный контейнер. А если мы посмотрим на его иерархию, то будет видно, что он порождается от TComponent. Следовательно не тянет за собой методов, свойств и событий для визуализации.

Теперь TFrame:

TFrame is a container for components; it can be nested within forms or other frames.

A frame, like a form, is a container for other components. It uses the same ownership mechanism as forms for automatic instantiation and destruction of the components on it, and the same parent-child relationships for synchronization of component properties


Т.Е. Это "почти форма", происходит от TScrollingWinControl (я опустил класс TCustomFrame, но он носит "достаточно промежуточный" характер). Из иерархии классов видно, что "ноги" у формы и фрейма растут из одного места. Фрейм тащит с собой всю прелесть визуализации.

Вот, на мой взгляд, основные различия между TFrame и TDataSet. А подход к их использованию зависит уже от конкретного проектирования классов. Я бы сформулировал такие правила:
-Если у Вас много визуальных компонент типа TEdit,TListVBox,TLabel и т.д. И правила их визуализации достаточно сложные (здесь читать, здесь не читать, здесь рыбу заворачивали), то это задача для фреймов.
-Если у Вас много различных подключений к БД и других не визуальных компонент, то это дело для датамодулей.
-Если много и того и другого, то естественно синтез обоих подходов.

Что касается использования TDataModule. Мне часто приходится решать задачи переноса данных из одной БД в другую. Я делаю примерно следующее:

Код:
class mySourceDataBase : public TDataModule
{
   //Здесь все, что касается доступа к БД
 ....
}

class myDestDataBase : public TDataModule
{
   //Здесь все, что касается доступа к БД
 ....
}


Таким образом имею два класса, практически на все случаи жизни. Это очень удобно. А на формах у меня только визуальные компоненты (TDBGrid e.t.c) и TDataSource для них.

Я считаю это наиболее правильным и с точки зрения ООП, и с точки зрения общего стиля программирования, и с точки зрения оптимальности.

Вот в кратце моя точка зрения.
10
25 марта 2005 года
Freeman
3.2K / / 06.03.2004
Цитата:
Originally posted by AlexandrVSmirno
Я бы сформулировал такие правила:
-Если у Вас много визуальных компонент типа TEdit,TListVBox,TLabel и т.д. И правила их визуализации достаточно сложные (здесь читать, здесь не читать, здесь рыбу заворачивали), то это задача для фреймов.


Это было бы слишком просто. Компоненты Борланд, как правило не позволяют полностью автоматизированно строить интерефейс пользователя на основе невизуальных компонентов. Из этого вытекает простое правило:
- Если компонентов для визуализации больше двух-трех и требуется их использование в нескольких разных местах, использование фреймов обязательно.

Т. е. мерилом объединения во фрейм является не сложность вывода как таковая, а повторное использования.

Для объединения же во фреймы по критерию сложности должно быть достаточно много невизуальных компонентов. На практике оно встречается гораздо реже, чем повторное использование групп визуальных компонентов.

Цитата:
Мне часто приходится решать задачи переноса данных из одной БД в другую.


Ты сейчас будешь смеяться. Задача, которую я решил при помощи фреймов, называется "Репликатор" и занимается как раз переносом данных из одной БД в другую.

Цитата:

Я делаю примерно следующее:
Код:
class mySourceDataBase : public TDataModule
{
   //Здесь все, что касается доступа к БД
 ....
}

class myDestDataBase : public TDataModule
{
   //Здесь все, что касается доступа к БД
 ....
}


Таким образом имею два класса, практически на все случаи жизни. Это очень удобно.


Или пример слишком упрощенный, или я понял его неверно. Мне тоже часто приходится иметь дело с переносом данных из одной БД в другую. Как правило, базы бывают разные. Например, в последней задаче был перенос из Oracle в Paradox и Interbase.
Если решать подобную задачу твоим способом, надо объявить общего предка для каждой БД и виртуальные методы для реализации требуемой функциональности, не зависящие от БД. Тогда модули данных заработают.

259
28 марта 2005 года
AlexandrVSmirno
1.4K / / 03.12.2004
Цитата:
Originally posted by smartsoft
Это было бы слишком просто. Компоненты Борланд, как правило не позволяют полностью автоматизированно строить интерефейс пользователя на основе невизуальных компонентов. Из этого вытекает простое правило:
- Если компонентов для визуализации больше двух-трех и требуется их использование в нескольких разных местах, использование фреймов обязательно.

Т. е. мерилом объединения во фрейм является не сложность вывода как таковая, а повторное использования.



Я же и говорю, что в принципе все зависит от конкретного подхода к проектированию классов.

На самом деле, что является предметом обсуждения? Есть два подхода:
1. Использовать контейнеры классов при проектировании.
2. Не использовать контейнеры классов при проектировании (так предлагает твой друг).

Достоинства и недостатки второго подхода мы здесь не обсуждаем. Итак. Предметом обсуждения является вопрос: Какаой базовый класс из стандартной VCL лучше использовать в качестве контейнера для классов в приложении TFrame или TDataModule? Я понял именно так.
На мой взгляд TFrame имеет смысл использовать, если необходимо реализовать достаточно сложное визуальное поведение формы. Скажем разместить несколько независимых окон на одной форме. (Это можно реализовать и с помощью чильд-форм, но зачастую это не эффективно. Этот инструмент я бы использовал в случае если необходимо много однотипных, а не разных окон). Делать же отдельный фрейм для работы с БД мне представляется не очень удобным. Ну зачем контейнеру содержащему sql-запросы Canvas или Scrolling или Border? На мой взгляд это лишнее. Я считаю, что все такого рода компоненты должны находиться всетаки в TDataModule. Что касается того, что Дата-модуль глобален по отношению ко всем формам и это создает неудобства, т.к. приходиться "размножать" компоненты доступа к БД, как раз наоборот, мне кажется, что эта проблема появляется от некачественного проектирования и привести все хотя бы к 3-НФ всегда можно.

Цитата:
Originally posted by smartsoft
Если решать подобную задачу твоим способом, надо объявить общего предка для каждой БД и виртуальные методы для реализации требуемой функциональности, не зависящие от БД. Тогда модули данных заработают.



Да пример конечно совсем примитивен и ты правильно уловил суть.

10
29 марта 2005 года
Freeman
3.2K / / 06.03.2004
Цитата:
Originally posted by AlexandrVSmirno
На мой взгляд TFrame имеет смысл использовать, если необходимо реализовать достаточно сложное визуальное поведение формы. Скажем разместить несколько независимых окон на одной форме. (Это можно реализовать и с помощью чильд-форм, но зачастую это не эффективно.


Не знаю, какие задачи приходится решать тебе, но я уже не первый раз сталкиваюсь с ситуацией, когда надо отобразить некий набор контролов на вкладке какой-нить формы и отдельно, скажем, в диалоговом окне. Прибамбасы Виндового интерфейса, так сказать. Без фреймов тут не обойтись.

Опять-таки, при решении задачи на первый план выходит "повторное использование дизайна", а "сложное поведение" добавляется уже потом, после обретения уверенности, что его не придется копировать еще на парочку форм.

Цитата:
Делать же отдельный фрейм для работы с БД мне представляется не очень удобным. Ну зачем контейнеру содержащему sql-запросы Canvas или Scrolling или Border? На мой взгляд это лишнее. Я считаю, что все такого рода компоненты должны находиться всетаки в TDataModule.


Или мы не понимаем друг друга, или ты утрируешь. Я не призываю размещать невидимые компоненты в видимых контейнерах, а просто хочу обратить внимание, что на практике очень часто нужны не просто запросы, а запросы + средства их визуализации.

Возьмем даже MDI-формы. Если их число неограниченно (как в Word, например), запастись запросами в модуле данных на всю оставшуюся жизнь ты не сможешь. Надо или создавать отдельные модули данных для каждого окна, или лепить компоненты запросов непосредственно в видимые контейнеры, т. е. формы.

А теперь представь задачу, описанную выше. Данные надо отображать не в разных окнах, а на вкладке мастера и по двойному клику где-нить в списке результатов, выводя диалоговое окно "Подробно". Куда лепить запросы? Только во фреймы.

Описанная задача характерна еще тем, что правила отображения данных намного сложнее правил их получения - обычно хватает одного запроса и одного TDataSource. Использование для них отдельного модуля данных бессмысленно.

Кстати, возможно, в этой задаче придется мне применить и модули данных. В качестве дальнейшего развития заказчик выдвинул требование автоматической работы, без вмешательства пользователя. Скорее всего, такая работа будет вестись вообще без интерфейса, поэтому загружать ресурсы системы неиспользуемыми объектами GDI и пр. было бы неразумно. Но это уже другая задача, а не та, которая была раньше. ;)

259
29 марта 2005 года
AlexandrVSmirno
1.4K / / 03.12.2004
Цитата:
Originally posted by smartsoft
Не знаю, какие задачи приходится решать тебе, но я уже не первый раз сталкиваюсь с ситуацией, когда надо отобразить некий набор контролов на вкладке какой-нить формы и отдельно, скажем, в диалоговом окне. Прибамбасы Виндового интерфейса, так сказать. Без фреймов тут не обойтись.

Опять-таки, при решении задачи на первый план выходит "повторное использование дизайна", а "сложное поведение" добавляется уже потом, после обретения уверенности, что его не придется копировать еще на парочку форм.



С этим я согласен. Повтороное использование дизайна это тоже как раз для фреймов.

Цитата:
Originally posted by smartsoft
Или мы не понимаем друг друга, или ты утрируешь. Я не призываю размещать невидимые компоненты в видимых контейнерах, а просто хочу обратить внимание, что на практике очень часто нужны не просто запросы, а запросы + средства их визуализации.

Возьмем даже MDI-формы. Если их число неограниченно (как в Word, например), запастись запросами в модуле данных на всю оставшуюся жизнь ты не сможешь. Надо или создавать отдельные модули данных для каждого окна, или лепить компоненты запросов непосредственно в видимые контейнеры, т. е. формы.



Ну положим каждой МДИ-форме по скл-запросу это тоже утрированно.

Вообще-то получилось очень полезное обсуждение. Жаль, что больше никто не присоединился. Я, например, несколько по другому взглянул на фреймы. До этого я как-то их слабо использовал. Теперь вижу, что это достаточно мощное средство. Кстати а как насчет TPanel. Похоже ведь.:)

У меня задачи с простым, я бы даже сказал примитивным интерфейсом. Не потому, что я не умею или считаю это не важным. Просто он не нужен. Зато работа с БД достаточно сложна. С большим количеством сложных аггрегаций и пересечений данных. То что называется вторичная обработка данных. И здесь DataModule меня вобщем то выручает. Я к тому, что мне больше нравится не Frames vs DataModules, а Frames and DataModules.

ЗЫ: Кстати о интерфейсе. Это тоже отдельный и интересный разговор.

10
29 марта 2005 года
Freeman
3.2K / / 06.03.2004
Цитата:
Originally posted by AlexandrVSmirno
Ну положим каждой МДИ-форме по скл-запросу это тоже утрированно.


Ой, не зарекайся! Например, пишешь ты бухгалтерскую программу или учет остатков на складах. И надо тебе, скажем, вывести в разных окнах результаты за разные месяцы или по разным складам. Пользователь хочет видеть их на экране одновременно, в уложенных черепицей окнах. Запросы различаются только параметрами. Куда их лепим?

Цитата:
Кстати а как насчет TPanel. Похоже ведь.:)


Опять утрируешь? Похоже, как хер на палец. ;)

Фрейм - единственный контейнер из видимых и невидимых, имеющий возможность повторного использования в процессе дизайна без создания специального пакета и регистрации в панели компонентов.

Цитата:
С большим количеством сложных аггрегаций и пересечений данных.


Мы такие вещи, как правило, стараемся делать на сервере, в виде хранимых процедур.

Цитата:
Я к тому, что мне больше нравится не Frames vs DataModules, а Frames and DataModules.


В процессе обсуждения постепенно выкристализовывается истниа. Теперь выходит уже именно так.

Цитата:
ЗЫ: Кстати о интерфейсе. Это тоже отдельный и интересный разговор.


Твоя очередь. :D

10
11 мая 2005 года
Freeman
3.2K / / 06.03.2004
Тема старая, но сегодня дал на нее ссылку и по случаю еще раз перечитал.
Цитата:
Originally posted by Freeman
Фрейм - единственный контейнер из видимых и невидимых, имеющий возможность повторного использования в процессе дизайна без создания специального пакета и регистрации в панели компонентов.


Вот где собака порылась! Чтобы модули данных заработали полностью как "невидимые фреймы", на панели инструментов должен быть инструмент "Data Module" рядом с "Frame" на вкладке "Standard", работающий точно также, но с модулями данных. Тогда будет полноценное визуальное повторное использование.

К сожалению, одна небезызвестная фирма предпочитает думать другим местом...

302
12 мая 2005 года
Sagittarius
648 / / 12.04.2003
Кстати, об интерфейсе и БД. Как вы считаете, имеют ли право на жизнь компоненты с закладки Data Controls (кроме TDBGrid), ведь для их адекватной работы нужно держать открытое соединение с БД?
10
12 мая 2005 года
Freeman
3.2K / / 06.03.2004
Цитата:
Originally posted by Sagittarius
Как вы считаете, имеют ли право на жизнь компоненты с закладки Data Controls (кроме TDBGrid), ведь для их адекватной работы нужно держать открытое соединение с БД?


Хочешь сказать, что для грида это не надо?

Вообще, вопрос некорректен, если брать глобально. Компоненты Data Controls предназначены для создания БД-приложений клиент-сервер, архитектура которой предусматривает наличие постоянного соединения с базой. Если же реализуется трехзвенка или что-то вроде "отложенной синхронизации", то извините меня, это совершенно другая задача, и решение у нее должно быть соответствующим.

302
13 мая 2005 года
Sagittarius
648 / / 12.04.2003
Цитата:
Originally posted by Freeman
Хочешь сказать, что для грида это не надо?

Вообще, вопрос некорректен, если брать глобально. Компоненты Data Controls предназначены для создания БД-приложений клиент-сервер, архитектура которой предусматривает наличие постоянного соединения с базой. Если же реализуется трехзвенка или что-то вроде "отложенной синхронизации", то извините меня, это совершенно другая задача, и решение у нее должно быть соответствующим.


Нет, я не хочу сказать, что для TDBGrid это не надо. Я пытался сказать, что кроме TDBGrid в реальных приложениях я не использую компоненты с Data Controls. Предпочитаю им замену обычным TEdit и иже с ним. А также стараюсь сократить количество запросов (объектов TADOQuery) до необходимого минимума, а основные из них располагать в TDataModule, который, в последствии, используется большинством форм.

10
13 мая 2005 года
Freeman
3.2K / / 06.03.2004
Цитата:
Originally posted by Sagittarius
Предпочитаю им замену обычным TEdit и иже с ним. А также стараюсь сократить количество запросов (объектов TADOQuery) до необходимого минимума


Это уже самоцель и дополнительный геморрой. DB-компоненты для того и были созданы, чтобы от него избавить. Понимаю, если бы ты писал на MFC или Java...

Кстати, DB-компоненты в VCL - единственный и работающий, но несколько своеобразный и ограниченный способ реализации архитектуры "документ-представление".

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог