Конференция "Прочее" » Как правильно наследоваться от TDataModule?
 
  • Рыбба (14.01.09 10:30) [0]
    Здраствуйте. В Делфи я новичок, так что сильно не пинайте.
    Решил сделать маленький проектик с базами с использованием наследования. Т.е. сделал какой-то каркас, а затем в проекте наследуешься от него. Сделал классы форм - все нормально наследуется и используется.
    Но хочу так же сделать и с TDataModule. Сделал общий датамодуль (TMyDM), а как наследоваться от него? Ведь в классах формы есть ссылки на TMyDM (датасурсы, гриды, вызовы процедур и прочее)?
    Если сделать новый датамодуль (TDM = class(TMyDM)) то придется вручную поменять ссылки на TDM, тогда смысл?

    Подскажите как правильно. Спасибо
  • Кит (14.01.09 10:50) [1]
    File > New > Other...
    [Тут вкладка с именем твоего проекта] > Ищешь твой датамодуль MyDM выбираешь внизу Inherit > Ok

    Усё.
  • Рыбба (14.01.09 12:00) [2]
    Прочитайте внимательней
  • MsGuns © (14.01.09 12:04) [3]
    Если вся (или почти вся) логика обмена с БД инкапсулируется в датамодуль, зачем делать от него наследника ?
    Мне почему-то кажется, что Вам надо реализовать несколько форм, работающих с разными экземплярами одних и тех же объектов связи с БД (как пример, два или более экземпляра одной и той же формы просмотра содержимого одного и того же запроса, но с разными параметрами). Если так, то для каждой формы не нужно создавать датамодуль по "образу и подобию" основого. Надо все объекты (датасеты обычно) располагать в самих формах, а вот некотрый функционал (например, обработка событий датасетов, обработка ошибок, установление соединения с БД и т.д.) реализовать в основном ДМ. Тогда при достаточной автономности интерфейсных модулей (форм, фрэймов и т.д.) Вы получите компактность и унифицированность кода.

    Есть, конечно, и другой способ, позволяющий все же избавить формы от датасетов - но для этого надо в датамодуле предусмотреть списки датасетов и сгородить недетскую логику по разруливанию их при открытиях и закрытиях форм. ИМХО, путь для обычного (не апп-сервера) совершенно неприемлимый, хотя и реализуемый.
  • MsGuns © (14.01.09 12:13) [4]
    Можно, конечно, и пойти тем путем, который, вероятно, выбрали Вы, т.е. каждой сес.. пардон, форме - по сер.. пардон, датамодулю. Но это, ИМХО, очень "раздробит" проектный код, сделав его трудно читаемым, да и вряд ли избавит Вас от кучи лишнего при реализациях "особенностей"

    ИМХО, более одного "базаданного" датамодуля имеет делать только если у Вас, например, более одной БД одновременно либо есть некий кусок (например, объявления классов в объектной БД), стоящий вне физических БД, как бы над ними, но актуальный для физических БД. Либо Вы хотите часть деклараций и реализации вынести из проекта для дальнейшего использования (например, в репозиторий) в других разработках.

    В любом случае не рекомендую без особой надобности использовать более одного датамодуля. Как показывает практика, множество проблем можно решить просто добавив в делфи собственные библиотеки юнитов (по образу и подобию делфишых)
  • Ega23 © (14.01.09 12:15) [5]
    type

     TMySuperPuperMegaForm = class (TForm)
     private
       procedure SetDataModule(Value : TMySuperMegaDataModule);
     public
       property MySuperMegaDataModule : TMySuperMegaDataModule read FMySuperMegaDataModule write SetDataModule;

     end;

    procedure TMySuperPuperMegaForm.SetDataModule(Value : TMySuperMegaDataModule);
    begin
     FMySuperMegaDataModule := Value;
     if Value=nil then Exit;

     Подключаем все контролы и всё остальное...
     ....
    end;

  • Рыбба (14.01.09 12:42) [6]
    [3], [4]
    Спасибо за ответ.
    Расскажу немного.
    На датамодуле-предке (TMyDM) находятся общие процедуры работы с БД, а также расположены компоненты подключения к серверу БД, несколько датасетов для операций с базой (например, для разовых выполнений каких-то запросов) и некоторые невизуальные компоненты. Ну, например, ImageList (который в себе хранит картинки, например, для разных состояний записи - проведен, не проведен, удален и прочее). Или, возможно, набор стилей для грида DevExpress. Соотственно, в некоторых формах есть ссылки, допустим на ImageList. После наследования эти ссылки должны вести не на предка, а на потомка. Во-вторых, в коде есть явное указание датамодуля, например в коде:
    with MyDM.DataSet do begin ... end;


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

    [5] Спасибо за пример. Попробую вечером. А визуально я могу сослаться на property MySuperMegaDataModule в дизайнере форм?
    Еще недостаток этого подхода по-моему: форма должна быть подключена практически везде для видимости. Всем видимый датамодуль как-то привычней... Но это уже, наверное, дело вкуса
  • Медвежонок Пятачок © (14.01.09 12:42) [7]
    Ведь в классах формы есть ссылки на TMyDM

    ну и пусть будут ссылки.
  • Медвежонок Пятачок © (14.01.09 12:47) [8]
    В любом случае не рекомендую без особой надобности использовать более одного датамодуля.

    С наследованием это никак не связано.
    У меня например базовый Dm и сто его наследников для разных библиотек доступа и разных субд.
    Но в приложении единственный экземпляр dm
  • Ega23 © (14.01.09 12:50) [9]

    > А визуально я могу сослаться на property MySuperMegaDataModule
    > в дизайнере форм?


    Ну если наприльником заточить - то пуркуа бы и не па. А смысл?
  • Медвежонок Пятачок © (14.01.09 12:52) [10]
    with MyDM.DataSet do begin ... end;

    with GetMyDataModuleMethod.DataSet do begin ... end;
  • Рыбба (14.01.09 13:02) [11]
    [9] При дизайне проекта в среде. Или всю привязку делать в рантайме?
    [10] А при визуальном проектировании?
  • Ega23 © (14.01.09 13:30) [12]

    > [9] При дизайне проекта в среде. Или всю привязку делать
    > в рантайме?
    > [10] А при визуальном проектировании?


    Я в рантайме делаю. Дизайн-тайм развращает....  :)

    Но можно сделать и для дизайн-тайм.
  • MsGuns © (14.01.09 14:04) [13]
    >Медвежонок Пятачок ©   (14.01.09 12:47) [8]
    >С наследованием это никак не связано.

     А я не нсоветовал наследовать

    >У меня например базовый Dm и сто его наследников для разных библиотек доступа и разных субд. Но в приложении единственный экземпляр dm

    Бога ради. Но я предпочитаю ОБЩИЙ код делать универсальным и выносить его вообще из проектов в библиотеку. Так просто удобнее ИМХО. И не нужно использовать наследование ИМХО оно здесь неуместно.

    >Рыбба   (14.01.09 12:42) [6]

    Ваш пример очень вписывается в "библиотечную схему". Все процедуры и функции библиотеки получают необходимые объекты в виде ссылок параметирами, сам ни к кому не обращаясь напрямую. И их можно (и нужно !) использовать в других "родственных" проектах.
    Если задача (не проект, а проектируемая система в целом) достаточно сложная, то общие алгоритмы, классы и т.д. предпочтительнее разбить на несколько юнитов. Опять же как в делфи :)

    Более того, библиотеки можно использовать и при смене предмета автоматизации, места работы и даже профспецифики :) С датамодулями это сделать сложнее.
  • Медвежонок Пятачок © (14.01.09 14:13) [14]
    Бога ради. Но я предпочитаю ОБЩИЙ код делать универсальным и выносить его вообще из проектов в библиотеку. Так просто удобнее ИМХО. И не нужно использовать наследование ИМХО оно здесь неуместно.

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

    так что "общий код" только в базовом классе.
  • MsGuns © (14.01.09 14:22) [15]
    >Базовый модуль содержит реализацию всей логики бизнес процессов.

    Аналогично для библиотечной технологии

    >Но при этом ничего не знает ни о компонентах доступа, ни о платформе.

    Кхе-кхе, это как ?

    >Наследники наоборот, понятия не имеют и не содержат никаких алгоритмов.
    >Но устанавливать соединение на конкретных компонентах доступа к конкретному серверу.

    А причем тут датамодуль ? На том, что ты пишешь, стоИт делфи, только я что-то не помню, чтоб там использовались датамодули

    >так что "общий код" только в базовом классе.

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

    У меня, кстати, библиотечным образом реализовано куча форм, всякие поиски, фильтры, диалоги и т.д. Так что в проекте не надо никаких форм, датамодулей и т.д. которые пусть они хоть вообще не содержат кода, но все же "тянут" на себя и ресурсы, и время, и утяжеляют проект, добавляя в него доп.файлы (вот не люблю я когда в рабочей папке сотни файлов, и всё !)

    Хотя, кончно, кому поп, кому попадья :)
  • Медвежонок Пятачок © (14.01.09 14:26) [16]
    Кхе-кхе, это как ?

    Обыкновенно. Вся работа идет на уровне TDataSet.
  • MsGuns © (14.01.09 14:29) [17]
    Ты ж сказал "ничего не зная о компонентах" и, тем более "платформе" :)

    "Как понимать тебя, Саид ?" (с)
  • Ega23 © (14.01.09 14:37) [18]

    > Ты ж сказал "ничего не зная о компонентах" и, тем более
    > "платформе" :)


    Всё потомок TDataSet.
  • Медвежонок Пятачок © (14.01.09 14:43) [19]
    Базовый модуль данных ничего не знает о компонетах (bde,ado,fibs,odac etc)
    И про сервер ничего не знает. Это может быть любой сервер или вообще файлы dbase/paradox

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

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

    В переопределенных методах никакой бизнес логики нет, голая техника типа такого

    function CreateSelectSQLComponent(const ASQLText : string; var AComponent : TComponent; AOpen : boolean; const AEditTableName,AkeyFields,AGeneratorName : string) : boolean; overload; override;

    итого: чтобы собрать новую версию на совершенно другом движке и компонентах уходит час - полтора.
  • Jeer © (14.01.09 15:04) [20]
    Мне вообще ничего практически не надо делать (изменять приложение), чтобы работать с большинством SQL-серверов :))
    Более того, обеспечена одновременно работа с многими SQL-серверами одним приложением. :))
  • Ega23 © (14.01.09 15:19) [21]

    > Мне вообще ничего практически не надо делать (изменять приложение),
    >  чтобы работать с большинством SQL-серверов :))
    > Более того, обеспечена одновременно работа с многими SQL-
    > серверами одним приложением. :))


    У слона всё равно длиннее.
    И толще.
  • Рыбба (14.01.09 15:47) [22]
    Почитал. Хочется сначала попробовать метод [5]. Однако не получается увидеть свойство MySuperMegaDataModule в дизайнере объектов. Не подскажите решение / ссылочку. Спасибо
  • Игорь Шевченко © (14.01.09 16:22) [23]
    Если рассматривать приложение в рамках парадигмы Model-View-Controller, то базовый datamodule вполне может быть абстрактной моделью, а его наследники - конкретными моделями.
    Не вижу ничего криминального в создании наследников datamodule, единственное что предложу автору - это не ссылаться нигде по имени на переменную конкретного экземпляра datamodule типа MyDm.MyDataSet
  • Рыбба (14.01.09 16:39) [24]
    [23] Допустим в коде я могу убрать ссылки (и то думаю будет непривычно), но как быть с ссылками в дизайн-тайме? Думается, что все-таки писать привязки в рантайме слишком громоздко
  • Ганя (14.01.09 16:43) [25]

    > Думается, что все-таки писать привязки в рантайме слишком
    > громоздко


    Советую писать их именно в ран тайм.
    Дело в том, что в силу некоторых косяков среды (а именно, периодического обниливания ссылок на внешние модули\формы в дизайнере), удобство работы "мышкой" полностью портится необходимостью ведения борьбы с этими "фичами"
  • Игорь Шевченко © (14.01.09 17:01) [26]

    > но как быть с ссылками в дизайн-тайме?


    какие ссылки в design-time имеются в виду ?
  • MsGuns © (14.01.09 17:20) [27]
    >Ega23 ©   (14.01.09 14:37) [18]
    >Всё потомок TDataSet.

    Кхе-кхе два раза, но, извиняюсь, кто у пресловутого датасета в отцах ходит, ась ?

    >Jeer ©   (14.01.09 15:04) [20]
    >Более того, обеспечена одновременно работа с многими SQL-серверами одним приложением. :))

    Осталось только выяснить крохотный вопросец - а что, собсна, умеет делать это самое приложение ? :)

    >Медвежонок Пятачок ©   (14.01.09 14:43) [19]
    >Базовый модуль данных ничего не знает о компонетах (bde,ado,fibs,odac etc)
    >И про сервер ничего не знает. Это может быть любой сервер или вообще файлы dbase/paradox
    >Но он все знает о том, как должны делаться инсерты/апдейты/делеты и прочее. Содержит всю >бизнес логику и все алгоритмы.

    А какой сиквель использует этот замечательный датамодуль и как на этот сиквель реагируют "любые" сервера ?
    И я все же так и не добился ответа на главное - а разве все это нельзя было сделать без датамодуля, а если можно, то в чем все-таки преимущество именно датамодуля ?

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

    Чем эта парадигма предпочтительнее следующей:
    "Когда я реализую новый сервер, то в первую очередь использую функционал библиотеки, а если его недостаточно, то пишу свой, иногда перенося его в те же библиотеки, расширяя их функции и уменьшая таким образом трудоемкость проектирования в перспектие ?"
  • Jeer © (14.01.09 17:27) [28]

    > MsGuns ©   (14.01.09 17:20) [27]
    > >Jeer ©   (14.01.09 15:04) [20]
    > >Более того, обеспечена одновременно работа с многими SQL-
    > серверами одним приложением. :))
    >
    > Осталось только выяснить крохотный вопросец - а что, собсна,
    >  умеет делать это самое приложение ? :)
    >


    OLAP
  • MsGuns © (14.01.09 17:35) [29]
    ну ты эта.. реально крут :)
  • Рыбба (14.01.09 17:44) [30]

    > какие ссылки в design-time имеются в виду ?

    Допустим привязка TADODataSet.Connection = TADOConnection в инспекторе свойств


    > Дело в том, что в силу некоторых косяков среды (а именно,
    >  периодического обниливания ссылок на внешние модули\формы
    > в дизайнере), удобство работы "мышкой" полностью портится
    > необходимостью ведения борьбы с этими "фичами"

    Слышал про проблему. Но если в проекте держать открытым датамодуль, то проблема исчезнет. По крайней мере видел этот способ решения
  • Игорь Шевченко © (14.01.09 18:30) [31]

    > Допустим привязка TADODataSet.Connection = TADOConnection
    > в инспекторе свойств


    В моем (например) случае connection хранится в своем datamodule не входящем в иерархию (connection-ов обычно меньше, чем DataSet-ов), соответственно, ссылка в design-time тоже наследуется.
    Если очень боязно за то, что пропадет, можно на событии Loaded предка в иерархии присвоить это свойство в run-time, тогда оно автоматически распространится на наследников.
  • MsGuns © (14.01.09 23:01) [32]
    >Рыбба   (14.01.09 17:44) [30]
    >> Дело в том, что в силу некоторых косяков среды (а именно,
    >>  периодического обниливания ссылок на внешние модули\формы
    >> в дизайнере), удобство работы "мышкой" полностью портится
    >> необходимостью ведения борьбы с этими "фичами"

    >Слышал про проблему. Но если в проекте держать открытым датамодуль, то >проблема исчезнет. По крайней мере видел этот способ решения

    Если это не секрет, о каких "фичах" речь ? Вот уже сколько лет дружу с делфей, но не видел и даже не слышал.

    ЗЫ. В целом ветка напоминает диспут о том, как монтировкой ковыряться в зубах. Как говорится, попутного ветра !
  • Медвежонок Пятачок © (15.01.09 10:22) [33]
    Вот уже сколько лет дружу с делфей, но не видел и даже не слышал.

    Просто у всех проекты разной степени сложности.
    Фича пропадания паблишед свойств-ссылок на компоненты известна очень давно.
  • Ega23 © (15.01.09 10:27) [34]

    > Если это не секрет, о каких "фичах" речь ? Вот уже сколько
    > лет дружу с делфей, но не видел и даже не слышал.


    А такая. Приходишь утром на работу. Запускаешь Delphi. Открываешь вчерашний проект (вчера перед выходом всё работало). Бах - а во всех ДБгридах пропали ссылки на датасорсы. И вообще, во всех ДБ-контролах пропали ссылки на датасорсы.
    И если по какой-то причине не залил в CVS, то приходит .ОПА.
  • MsGuns © (15.01.09 11:48) [35]
    >Бах - а во всех ДБгридах пропали ссылки на датасорсы. И вообще, во всех ДБ-контролах >пропали ссылки на датасорсы.

    Ух ты ! А как сделать такой веселый "Бах" ?
    :)
  • Ega23 © (15.01.09 11:52) [36]

    > Ух ты ! А как сделать такой веселый "Бах" ?


    А пёс его знает. Я серьёзно. Несколько раз натыкался. Хорошо ещё, если сразу заметил и нормальную версию из CVS выгрузил. А то бывает, что уже изменений навносил кучу.
  • vuk © (15.01.09 12:12) [37]
    У нас в проектах не принято выносить объекты данных в датамодули. Всё живет непосредственно на фреймах, благо они, как правило, небольшие. Можно, конечно, было бы всё, что касается данных, выносить в датамодули, но это привело бы к увеличению количества модулей в проекте и усложнению взаимодействия.

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

    Еще есть главный датамодуль, который содержит в себе соединения к разным БД, умеет работать со всякими сервисами типа нотификаций и конфигурирования и т.д.

    А базовый датамодуль есть, но он общий для всех проектов и в нем прописана общая минимальная необходимая для всех проектов функциональность для главного датамодуля.
  • Ega23 © (15.01.09 12:30) [38]

    > У нас в проектах не принято выносить объекты данных в датамодули.
    >  Всё живет непосредственно на фреймах, благо они, как правило,
    >  небольшие.


    Угу, я "опытным путём" к такой же идеологии пришёл.
  • Медвежонок Пятачок © (15.01.09 12:46) [39]
    аналогично.
    все "визуализируемые" датасеты лежат там же, где и датааваре контролы.
  • Игорь Шевченко © (15.01.09 12:52) [40]
    Ega23 ©   (15.01.09 12:30) [38]
    Медвежонок Пятачок ©   (15.01.09 12:46) [39]

    А если к конкретному датасету потребуется обратиться из другой (возможно невизуальной) части проекта ?
    (причем, к уже открытому)
  • Медвежонок Пятачок © (15.01.09 12:55) [41]
    не, я так я не жмусь. если надо в невизуальной части проекта получить доступ к объекту БД, я всегда использую новый экземпляр.
  • Игорь Шевченко © (15.01.09 12:59) [42]
    Медвежонок Пятачок ©   (15.01.09 12:55) [41]


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


    Ключевое слово в моем посте - к уже открытому (нужным образом отфильтрованному, отсортированному и т.п.)
    Ты предлагаешь в этом случае делать клон, применять все те же критерии выборки и работать с клоном ?
  • Ega23 © (15.01.09 12:59) [43]

    > А если к конкретному датасету потребуется обратиться из
    > другой (возможно невизуальной) части проекта ?
    > (причем, к уже открытому)


    Никто не мешает для таких дел завести отдельный DataModule. Но именно для таких дел, а не помойку из него устраивать.
  • vuk © (15.01.09 13:09) [44]
    to Игорь Шевченко ©   (15.01.09 12:52) [40]:
    >А если к конкретному датасету потребуется обратиться из другой
    >(возможно невизуальной) части проекта ?
    >(причем, к уже открытому)
    Передать туда датасет через параметр никто не запрещал. Но, честно говоря, я не припомню, чтобы такое когда-либо понадобилось.
  • Jeer © (15.01.09 13:14) [45]

    > vuk ©   (15.01.09 12:12) [37]
    >
    > У нас в проектах не принято выносить объекты данных в датамодули.
    >


    Аналогично, тем более, что имеется несколько базовых форм с датасетами и db_компонентами от которых потом наследуются все прикладные формы.
  • Медвежонок Пятачок © (15.01.09 14:10) [46]
    Ключевое слово в моем посте - к уже открытому (нужным образом отфильтрованному, отсортированному и т.п.)
    Ты предлагаешь в этом случае делать клон, применять все те же критерии выборки и работать с клоном ?


    А понял.
    У меня если честно нет таких проблем.
    Поясняю.
    Допустим есть грид, в котором юзер ввел свои условия фильтрации и сортировки. Набор данных готов для обработки.
    Что я делаю в этом случае?

    Мой грид имеет волшебный метод :

    function BatchProcess(ACallBack : TBlaBlaBlaCallBack; AUserData : Pointer; AWholeDataSet : boolean = False) : integer;

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

    В общем такое вот решение.
  • Рыбба (15.01.09 15:04) [47]
    Т.е. один датамодуль общий (где прописана общая функциональность). Если необходим(ы), то еще датасет(ы), нужный для конкретного проекта. И датасеты на конкретных формах? В таком случае эти датасеты ссылаются на один из датамодулей для, например, связки с Connection. Вообщем, так?
  • Jeer © (15.01.09 15:06) [48]
    Я к этому пришел довольно быстро.
    Унификация другого не дает сделать.
  • Медвежонок Пятачок © (15.01.09 15:08) [49]
    В таком случае эти датасеты ссылаются на один из датамодулей

    В таком случае верхняя форма в иерархии форм, которая работает с БД имеет виртуальный метод

    procedure SetDBConnection(AConnection : TSomeDatabaseConnection)
  • MsGuns © (15.01.09 15:10) [50]
    По поводу ненужности централизации обмена с БД (технология фрэймов от vuk)
    Редко бывают приложения БД, которые стразу после запуска требуют открытия всех окон и панелек. Все это по необходимости. Т.е. каждая форма (фрэйм) при первой активации должна самостоятельно устаналивать соединение и также содержать в себе весь код по обмену независимо от остальных - я правильно понял ? Например, всяческие поиски, сортировки, статусные строки, сообщения и т.д. фрэйм должен реализовывать самостоятельно ? Грубо говоря, у меня есть 20 форм в проекте, в которых отображаются РАЗНЫЕ объекты БД, но вышеуказанные фичи у них одинаковые. Как  я понял, надо создать один базовый фрэйм, где и реализовать общее, а затем наплодить от него 20 наслелдников, реализующих специфику. Способ, ИМХО, фиговенький и ведет к чрезмерной загруженности проекта модуоями, но ладно, проглотим.
    Но вот что интересно - каждый такой фрэйм будет самостоятельно соединяться с базой, открывать датасеты, в т.ч. вспомогательные (например, справочники), УЖЕ ОТКРЫТЫЕ в других фрэймах и т.д. Замечательно просто !
    А при открытии нового проекта, если он на 80% схож с написанным, предлагается всю эту кухню с кучей фрэймов тащить в него ? И еще строить из них генеалогические деревья наследования ибо эти 20% тоже как-то надо реализовать :)

     И кто-то берется утвержать, что такая технология лучше датамодульной ?
  • Медвежонок Пятачок © (15.01.09 15:16) [51]
    Но вот что интересно - каждый такой фрэйм будет самостоятельно соединяться с базой

    Ты про TDatabase в детстве читал?
  • Игорь Шевченко © (15.01.09 15:17) [52]
    vuk ©   (15.01.09 13:09) [44]


    > Передать туда датасет через параметр никто не запрещал.
    > Но, честно говоря, я не припомню, чтобы такое когда-либо
    > понадобилось.


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

    Ega23 ©   (15.01.09 12:59) [43]


    > Никто не мешает для таких дел завести отдельный DataModule.
    >  Но именно для таких дел, а не помойку из него устраивать.
    >


    В моих постах есть хоть один намек на предложение устроить помойку ? Если не трудно, ткни пожалуйста в номер поста.

    Медвежонок Пятачок ©   (15.01.09 14:10) [46]


    > Мой грид имеет волшебный метод :
    >
    > function BatchProcess(ACallBack : TBlaBlaBlaCallBack; AUserData
    > : Pointer; AWholeDataSet : boolean = False) : integer;


    У меня в датамодуле могут быть сосредоточены конкретные алгоритмы не имеющие никакого отношения к гридам, формам и контролам. И я хочу эти алгоритмы использовать в невизуальных приложениях.

    У меня предок таких датамодулей реализует один или несколько интерфейсов, соответственно, конкретная реализация в наследниках выглядит по-разному, обращение к датамодулям идет через методы интерфейса, ну а наследовать удобно, для того, чтобы часть методов вынести в базовый класс.
  • MsGuns © (15.01.09 15:17) [53]
    >Jeer ©   (15.01.09 13:14) [45]
    >тем более, что имеется несколько базовых форм с датасетами и db_компонентами от которых >потом наследуются все прикладные формы.

    А вот не стОит, ИМХО, смешивать визуализацию и все с нею связанное (сервисы на клиенте), где, действительно, сам Бог велел использовать наследование и инкапсуляцию, с собственно логикой обмена клиент-сервер, в общем случае совершенно независимой от "экрана".
  • Jeer © (15.01.09 15:19) [54]

    > MsGuns ©   (15.01.09 15:10) [50]


    Ганс, ты не в ту степь полез.
    Я что должен открыть туевую хучу датасетов в датамодуле и держать их таковыми для того, что вдруг откроется какая-то визуальная форма, где хрен знает что может потребоваться ? О чем, ты, друг ?
  • Медвежонок Пятачок © (15.01.09 15:20) [55]
    У меня в датамодуле могут быть сосредоточены конкретные алгоритмы не имеющие никакого отношения к гридам, формам и контролам. И я хочу эти алгоритмы использовать в невизуальных приложениях.

    Ну так нет проблем.
    Надо просто экземпляры создавать внутри этих алгороитмов.
    Тогда этот модуль будет действительно универсальным и заюзать его можно будет и в гуи и в консоли даже не заглядывая внутрь реализации.
  • Медвежонок Пятачок © (15.01.09 15:26) [56]
    Если же имелось ввиду использовать алгоритмы везде на произвольных датасетах, подготовленных в других модулях, то у меня такая парадигма:

    делаются методы:

    1. "Сделай_ЭТО_с_этой_таблицей_в_БД_на_основе_таких-то условий"
    2. "Сделай_тоже_самое_с_переданным_датасетом"

    дальше посто структурируем процедурно код.
    в первой процедуре готовим свой датасет и вызываем второй метод.
  • MsGuns © (15.01.09 15:34) [57]
    Вот пример "из жизни"
    Есть достаточно сложный многоступенчатый алгоритм расчета и формирования таблицы применяемости деталей и сборок в изделии, реализуемый на сервере и клиенте в объемном соотношении примерно 20 к 80 (на то есть ряд объективных причин, например то, что данные извлекаются с разных Скл-серверов и нескольких локальных баз).

    Этот алгоритм часто-густо используется :

    1) Для визуализации конструкторского состава (КСИ) изделия в виде дерева или таблицы, т.е. непосредственно "как есть"

    2) Для дальнейшего использования при вторичных выборках, например при составлении план-графика выпуска изделий

    3) При выгрузки для печати

    Собственно отображать КСИ у пользователя на экране ПК нужно только в первом случае (для этого написано пара-тройка приложений), в остальных случаях, а их десятки, отображать не нужно вообще. Если бы я реализовал КСИ на фрэйме, то пришлось бы каждый раз подключать его к проекту, создавать при запуске вместе с кучей никогда не показываемых визуальных компонентов, заполнять всевозможные пояснительные и прочие котнролы а затем все это килять.
    Спрашивается вопрос: а нафига столько лишней работы, пусть даже выполняемой "железкой" ?

    Напомню, что КСИ использует несколько соединений, практически полное описание модели данных "классовым" способом вместе с функционалом, тучу специфических типов данных и т.д.
    Которые можно было бы реализовать тоже фрэймом, конечно :)))

    Воображаю, что из себя в этом случае представляли бы исходники - умереть и повеситься :))
  • Игорь Шевченко © (15.01.09 15:41) [58]
    Медвежонок Пятачок ©   (15.01.09 15:20) [55]


    > Надо просто экземпляры создавать внутри этих алгороитмов.


    Э...не понял мысли


    >
    > Тогда этот модуль будет действительно универсальным и заюзать
    > его можно будет и в гуи и в консоли даже не заглядывая внутрь
    > реализации.


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

    Не видел нигде статьи с заголовком datamodule inheritance considered harmful
  • Jeer © (15.01.09 15:44) [59]

    > Если бы я реализовал КСИ на фрэйме, то пришлось бы каждый
    > раз подключать его к проекту, создавать при запуске вместе
    > с кучей никогда не показываемых визуальных компонентов,
    > заполнять всевозможные пояснительные и прочие котнролы а
    > затем все это килять.


    Серег, ну чего ты трындишь ?
    Визуализирующая форма для чего ? Правильно - для визуализации + возможно для редактирования.
    Все.
    Отдельные невизуальные механизмы ( уникальные  для какого-либо проекта ) конечно же надо реализововать там, где это удобнее.
    Но при чем тут унификация.
    Ведь наследование - это прежде всего унификация механизмов + добавочка необходимая.
  • Медвежонок Пятачок © (15.01.09 15:45) [60]
    > Надо просто экземпляры создавать внутри этих алгороитмов.
    Э...не понял мысли

    ну выше (после того, как некоторые сказали, что все датасеты лежат рядом с dbaware) было спрошено про то, а что делать если есть библиотечные алгоритмы, которые хочется применить к датасетам, которые используются еще для чего-то

    так вот я в таких библиотечных алгоритмах создаю датасеты на рантайме ну или в дизайне лежащие в датамодуле.

    или я чего-то не понял в самом вопросе.

    в общем у меня нет датасетов двойного и тройного назначения.
  • Игорь Шевченко © (15.01.09 15:58) [61]
    Медвежонок Пятачок ©   (15.01.09 15:45) [60]


    > так вот я в таких библиотечных алгоритмах создаю датасеты
    > на рантайме ну или в дизайне лежащие в датамодуле.


    Ну вот и я тоже самое делаю


    > в общем у меня нет датасетов двойного и тройного назначения.


    У меня их тоже нету. У меня нету даже датамодулей двойного назначения. В том-то и смысл, что назначение всегда одно, а вот использование в разных приложениях по мере потребности в том самом назначении - это имеется.
    Через датамодули сделано потому, что просто удобнее и писать меньше.
    Можно и в ран-тайме все объекты создавать, но не вижу смысла.
  • MsGuns © (15.01.09 16:15) [62]
    >Jeer ©   (15.01.09 15:44) [59]
    >Серег, ну чего ты трындишь ?
    >Визуализирующая форма для чего ? Правильно - для визуализации + возможно для >редактирования.
    >Все.

     Смотря что считать визуализацией.
    Есть такая штука - запасы называется. Они состоят, грубо говоря, из остатка на складе и задела.
    И то, и другое, показываются практически одинаково, но расчитываются совершенно по-разному.
    Эти самые остатки в одном приложении можно посмотреть в надцати местах: из дерева, из таблицы КСИ, из формы деталоизированной информации по детале(сборки) и еще тучи разных мест формы. Я реализую это с помощью одной разъединственной формочки с сеткой и панелькой динамически "подстриваемой" под нужные контролы отображения деталей. По клику формочка создается, настраивается (заголовок стрингридов, эдиты, чекбоксы, лабельки и т.д, - описания "настроек" в том ДАТАМОДУЛЕ),  в ДАТАМОДУЛЕ выполняется нужная выборка и контролы заполняются инфой из списка, заполненного соротв-й функцией ДАТАМОДУЛЯ. Который, выполнив выборку, закрывает НД. Что здесь визуализация ? ДМ не визуализирует сам, но обеспечивает подкачку требуемой инфы ИЗВЕСТНЫМ ТОЛЬКО ЕМУ СПОСОБОМ.
    Вот нафига тут вообще наследование ?

    >Отдельные невизуальные механизмы ( уникальные  для какого-либо проекта ) конечно же надо >реализововать там, где это удобнее.

     И я об этом же

    >Но при чем тут унификация.
    >Ведь наследование - это прежде всего унификация механизмов + добавочка необходимая.

     И я об этом же. Только говорю о том, что не следует это самое наследование пихать в каждую дырку.
  • Медвежонок Пятачок © (15.01.09 16:20) [63]
    не вижу препятствий.
    базовый фрейм с датасентом и функцией "подкачки"
    три наследника.
    с тривью, гридом и еще с чем-нибудь.
  • vuk © (15.01.09 16:24) [64]
    to MsGuns ©   (15.01.09 15:10) [50]:
    >Т.е. каждая форма (фрэйм) при первой активации должна самостоятельно
    >устаналивать соединение и также содержать в себе весь код по обмену
    >независимо от остальных - я правильно понял ?

    "В действительности всё не так, как на самом деле." (с) не я
    Все обстоит совсем не так как описано. По крайней мере у нас.

    >Т.е. каждая форма (фрэйм) при первой активации должна самостоятельно устаналивать соединение

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

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

    >Например, всяческие поиски, сортировки, статусные строки,
    >сообщения и т.д. фрэйм должен реализовывать самостоятельно ?
    Поиск и сортировка - это либо функция гридов (раелизовано один раз и навсегда) либо параметры выборок (зависит от контекста). Статусные строки и сообщения зависят от контекста.

    >Грубо говоря, у меня есть 20 форм в проекте, в которых отображаются
    >РАЗНЫЕ объекты БД, но вышеуказанные фичи у них одинаковые.
    Не понял. Если объекты разные, то они и отображаются, видимо, по-разному. И функциональность разная. Какие фичи будут одинаковыми?

    >Как  я понял, надо создать один базовый фрэйм, где и реализовать
    >общее, а затем наплодить от него 20 наслелдников, реализующих специфику.
    У нас в проекте больше сотни основных форм, к ним еще полторы сотни всяких диалоговых окон. И ничего. Есть один общий предок у фреймов, где расписана внутренняя функциональность по автоматическому назначению соединений с БД и т.п.

    >Но вот что интересно - каждый такой фрэйм будет самостоятельно соединяться с базой,
    >открывать датасеты, в т.ч. вспомогательные (например, справочники), УЖЕ ОТКРЫТЫЕ
    >в других фрэймах и т.д. Замечательно просто !

    Про соединения с базой я уже сказал. Оно одно на все приложение для одной БД (если приложение использует несколько БД, количество открытых соединений будет соответствовать числу используемых в данный момент БД). Вспомогательные наборы данных в 99% случаев зависят от контекста, и поэтому все равно в разных случаях будут разными. На справочники из десятка записей - пофиг, нагрузку на базу создают не они.
    Все, что зависит от контекста имеет одну особенность. Если будем вытаскивать всю работу с данными в модели данных, то на каждый фрейм понадобится создавать свой модуль данных, заточенный именно под этот фрейм. Если один фрейм используется в нескольких местах, то контекст во всех случаях, скорее всего, будет разным, использовать один источник данных нельзя и все равно придется подключаться к разным наборам данных. То есть каждый экземпляр фрейма будет работать со своим экземпляром модуля данных. В общем увеличение количества модулей в проекте процентов так на 50. И нафига это всё, если гораздо проще и прозрачнее структура, когда фрейм работающий с данными сам получает эти данные и вся функциональность полностью им реализована и внешние связи сведены к минимуму? Ведь это проще и отлаживать и расширять.
  • kaif © (15.01.09 16:29) [65]
    Для меня датамолуль это просто контейнер для невизуальных компонентов. Там я обычно держу:

    1. ImageList-ы с пиктограммами, если хочу их иметь постоянно под рукой для всяких меню и кнопок.
    2. Компонент соединения с базой данных и компонент транзакции по умолчанию на чтение.
    3. Компонент TApplication для обработки событий уровня приложения, например, глобальную обработку исключений.
    4. Компоненты для мониторинга (например, SQL-запросов)
    5. Иногда (очень редко!) некоторые датасеты маленьких часто используемых справочников, например, справочника валют.

    Но я пишу двузвенки. Возможно для писателей трехзвенок подход должен быть иным.
  • kaif © (15.01.09 16:32) [66]
    К тому же я пишу двузвенки для IB. А там нет проблем с одновременным стартом множества транзакций в рамках одного приложения. Поэтому и датасеты у меня раскиданы по окнам, а не сконцентрированы в каком-либо глобальном датамодуле. Для приложений баз данных с более критическими ограничениями на транзакции, может быть имеет смысл все помещать в датамодуль. Например, иногда, если я пишу приложения для Access, я все датасеты именно туда и помещаю. Так как в случае с Access так проще.

    Единого решения здесь быть не может.
  • vuk © (15.01.09 16:32) [67]
    to Игорь Шевченко ©   (15.01.09 15:17) [52]
    А догматизм он вообще вреден. Если мне нужно будет отделить логику от отображения, то я отделю. Хоть датамодулем, хоть как. Но я не буду отделять её всегда. У нас большая часть логики живет в MSSQL, а клиент, в основном, только отображением занимается.
  • Игорь Шевченко © (15.01.09 16:39) [68]
    vuk ©   (15.01.09 16:32) [67]


    > У нас большая часть логики живет в MSSQL, а клиент, в основном,
    >  только отображением занимается.


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


    > А догматизм он вообще вреден.


    Безусловно.


    > Если мне нужно будет отделить логику от отображения, то
    > я отделю. Хоть датамодулем, хоть как. Но я не буду отделять
    > её всегда.


    Я скорее не буду смешивать ее с отображением, впрочем, все как всегда зависит от задачи.
  • MsGuns © (15.01.09 16:41) [69]
    >vuk ©   (15.01.09 16:24) [64]

    <последний абзац>

    Я так и не понял зачем для каждого фрэйма создавать свой модуль данных ?  Я же писал - грид, источник, НАБОР ДАННЫХ - в фрйэм, а алгоритмику выборок (апдейтов), как и всю непрописанную в сетке функциональность датасета (например, события) - в датамодуль.

    Зачем в каждом фрэйме (путь даже у предка) иметь СВОЙ код по обработке фактически одного и того же ? Это как раз и есть НЕунификация логики, а совсем наоборот. Т.е. для приведенного выше примера с КСИ мне бы надо было по Вашей технологии создать туеву хучу фрйэмов для каждого вида инфы (пусть даже с минимальным кодом с учетом наследования) не смотря на то, что отличаются они по минимуму ? Вместо этого я создал модель детальной визуализации объектов, положил ее в датамодуль и использую при построении каждой формочки при помощи десятка строк кода. Т.е. у меня один датамодуль (правда немаленький), одна форма с минимумом контролов и кода - и все.
    ИМХО, куда проще разобраться с юнитом в 400 строк кода, чем с двумя десятками фрэймов, унаследованных друг от дружки.

    Хотя, конечно, каждый поп сам свой устав пишет :)
  • vuk © (15.01.09 17:04) [70]
    to Игорь Шевченко ©   (15.01.09 16:39) [68]
    >Я скорее не буду смешивать ее с отображением,
    >впрочем, все как всегда зависит от задачи.
    А я не вижу причин разделять данные и их отображение, если, как это у нас делается, выборки заточены под конкретное приминение и большее нигде не используются. Если же понадобится какой-то алгоритм реализовать отдельно от всего остального, то средства будут использованы адекватные задаче - где-то вынесение на сервер, где-то датамодули...

    to MsGuns ©   (15.01.09 16:41) [69]
    Что такое алгоритмика выборок и апдейтов я в упор не понял. У нас всё живет только через хранимые процедуры и всех алгоритмов при работе с ними - параметры подставить.
  • Игорь Шевченко © (15.01.09 17:38) [71]
    vuk ©   (15.01.09 17:04) [70]


    > А я не вижу причин разделять данные и их отображение, если,
    >  как это у нас делается, выборки заточены под конкретное
    > приминение и большее нигде не используются.


    У нас обычно используются (где-то еще). Гораздо хуже бывает, когда надо использовать отдельно, а оно уже встроено в компоненты отображения как в салат с озерными грибками. Тогда, разумеется, делается подробная копия алгоритма со всеми его причудами, но без визуальной части. И начинаются страсти с сопровождением.
    Нафиг-нафиг.

    Ключевые слова здесь - "у нас делается" и "у нас делается".
  • Медвежонок Пятачок © (15.01.09 17:40) [72]
    Тогда, разумеется, делается подробная копия алгоритма со всеми его причудами,

    Либо экспресс-рефакторинг для недопущения такого безобразия.
  • Игорь Шевченко © (15.01.09 17:46) [73]
    Медвежонок Пятачок ©   (15.01.09 17:40) [72]


    > Либо экспресс-рефакторинг для недопущения такого безобразия.


    За это никто не платит. А экспресс-рефакторинг немаленького древнего проекта плюс экспресс-тестирование результатов этого рефакторинга обойдутся в довольно круглую сумму.
  • Медвежонок Пятачок © (15.01.09 17:53) [74]
    нет, не проекта, а куска проекта, для которого потребовался внезапный копи-паст.
  • Игорь Шевченко © (15.01.09 18:42) [75]
    Медвежонок Пятачок ©   (15.01.09 17:53) [74]

    Так кусок проекта потом будет встроен в проект же. И тестировать придется как кусок отдельно, так и проект в целом, а оно муторно. По-правильному нужно, разумеется, провести рефакторинг и кучу тестирований, по жизни проще скопипастить. Все зависит от геморройности исходного материала.
  • Медвежонок Пятачок © (15.01.09 18:45) [76]
    ну изначально-то все равно не написать так, чтобы потом обо что-то не уколоться.

    не, теоретически/идеалистически конечно можно и должно. когда есть тз со всеми требованиями на весь жизненный цикл, есть архитектор, постановщик, тестировщики и прочие сказочные персонажи.
  • Игорь Шевченко © (15.01.09 18:57) [77]
    Медвежонок Пятачок ©   (15.01.09 18:45) [76]


    > ну изначально-то все равно не написать так, чтобы потом
    > обо что-то не уколоться.


    Безусловно.


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


    "Жаль только, жить в эту пору прекрасную, уж не придется ни мне, ни тебе"
    (с)
  • MsGuns © (15.01.09 21:05) [78]
    >vuk ©   (15.01.09 17:04) [70]
    >Что такое алгоритмика выборок и апдейтов я в упор не понял. У нас всё >живет только через хранимые процедуры и всех алгоритмов при работе с >ними - параметры подставить.

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

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

    С наилучшими
  • vuk © (15.01.09 21:49) [79]
    Если говорить о файловых БД и о запросах, генерируемых на клиенте, то там свои заморочки. Там есть смысл оформлять отдельно алгоритмы генерации запросов. Но это не имеет отношения к датамодулям. Но всё это только для файловых БД. Для клиент-серверных же генерировать запросы в клиенте при наличии хранимых процедур - довольно странное занятие.

    Я писал о том, с чем работаю. И ничего никому не собираюсь навязывать.
 
Конференция "Прочее" » Как правильно наследоваться от TDataModule?
Есть новые Нет новых   [134453   +34][b:0.001][p:0.002]