Здравствуйте, DemAS, Вы писали:
DAS> Есть база данных. В ней есть таблицы. Талицы справочники представляют собой какие-то сущности: например — поставщики, товары, адреса....
Тема очень большая, поэтому расскажу в двух словах как делается у нас. Действительно, самый надежный способ это отображать "сущности" базы данных на классы.
Чтение-запись в БД не встраивается в сами классы представления данных. Причин очень много, в том числе:
Эффективность
Более четкое разделение приложения на подсистемы.
Нужно будет спланировать механизмы синхронизации представления данных внутри программы. В том числе такие штуки как каскадное удаление.
Пользовательский интерфейс должен быть одним из способов управления данными. Потому что через некоторое время захочется прикручивать подобие автоматизации, и если сразу не предусмотреть изолированность данных от их представления, то потом прийдется все переписывать с нуля.
Транзакционность на уровне программы. Если объектов будет очень много (да и когда их мало, тоже не помешает) нужно будет реализовать надежный механизм перехода системы из одного состояния в другое. Например, при записи объектам будут назначаться идентификаторы и будут сбрасываться признаки изменения. Если происходит сбой и последующий откат транзакции в базе данных, то нужно вернуть все объеты в первоначальное состояние. За два года лучше, чем использование полных копии данных, я не придумал.
Тут сейчас другие напишут
А если опускаться до уровня — как именно это реализуется, то описания хватит на целую книгу
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Здравствуйте, DemAS, Вы писали:
DAS>Здравствуйте, Коваленко Дмитрий, Вы писали:
DAS> А куда оно встраивается. Писать для этого отдельные классы. Каким образом они будут связаны с классами-сущностями (Поставщик, Товар..) ?
В программу, куда же еще
Попробую кратко объяснить, что я имею в виду. У нас используется следующая архитекутра приложения хранения данных: Главный контейнер данных. Пусть он будет называться Document. В его обязанности входит:
Управление списком копий данных. Методы StartTrandaction, CommitTransaction, RollbackTransaction. Имеется в виду не транзакции в базе данных, а транзакции внутри документа (ну или набора данных) на уровне программы.
Метод, исторически названный Data, который возвращает текущую копию данных. Например, текущая копия может быть последним элементом списка.
Чтение-запись данных из базы данных. Методы SaveToDatabase, LoadFromDatabase. Перед чтением/записью начинается транзакционное изменение данных — через вышеуказанные методы
Получение уведомления об изменении данных и их транслирование на уровень пользовательского интерфейса. То есть в Document есть обратная связь с просмотром и редактированием данных юзером.
Вообще говоря, этот Document оформлен в виде COM объекта и он же представляет собой точку входа для доступа к данным через интерфейсы автоматизации.
Контейнер данных. Здесь хранятся сами данные и связи между ними.
Наборы данных. Например, поставщик, покупатель, список товаров
Контроллер. Специальный объект, который получает уведомления от данных и обеспечивает их синхронизацию. Формально он же, обработав событие, уведомляет главный контейнер, об изменении.
То есть, как видишь, чтение-запись отделенно от самих данных, поскольку они в этих операциях полностью пассивны. Фактически пишутся не те объекты, которые создал юзер, а их копии. Если операция прошла успешно — оригинал выкидывается, а копия становится актуальной. Если сбой — мы выкинем копию и вернемся к исходному состоянию.
Если интересно, можно еще пообщаться — у меня сечас выход из глубокого погружения, после которого потрепаться — единственный способ не навредить своей работе
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Здравствуйте, Коваленко Дмитрий, Вы писали:
ГВ>>Ну вот те раз. Начали за здравие а закончили... признанием в любви к stateless-модели.
КД>Вы чего при детях выражаетесь ? КД>Двунаправленный обмен данных подразумевает наличие сервера приложений. По крайней мере, если сервером базы данных является InterBase, то из него app-сервер не сделаешь.
Из сервера БД app-сервер вообще сделать сложно (хотя иногда можно).
КД>А я трезво оцениваю свои возможности и возможности нашей команды — мы такую архитектуру ПО просто не потянем.
Потянете, вы и так её тянете, просто размазали сложность по нескольким независимым подсистемам.
КД>А может нам просто нужен новый архитектор системы
Коней на переправе не меняют.
КД>А с другой стороны, что именно должен увидеть юзер, когда редактируемые данные изменились? Предупреждение в строке состояния ? Дык, как я уже сказал, это можно отложить до момента записи и сравнить дату модификации, которую мы прочитали при загрузке, с той, которую мы увидим на момент записи. Во время записи — мы её обновим.
Это всё верно, но только для относительно простых случаев. Есть ещё несколько соображений. Например, юзер А тратит много времени на обновление какой-то записи, тогда как другой (Б) в это время вносит в неё изменения и тем самым блокирует для Б возможность обновить запись. Что делать? По идее — А должен перечитать запись и отредактировать её заново. Всё бы хорошо, но ему снова придётся тратить время (и нервы) на сию операцию. И так далее и тому подобное. А в идеале Б просто не должен получить доступ на обновление к записи, которую уже захватил А.
Другой вариант. Запись (вернее — логический обновляемый объект) состоит из тучи мелких связанных записей, которые могут обновляться независимо (допустим — через drill-down навигацию), притом обновление одной из них может привести к недопустимости обновления агрегата, который при такой схеме и знать не будет о том, что какая-то его часть изменилась. Здесь вроде бы, логически, выход в том, чтобы вынести всю логику контроля целостности на... сервер БД и привет app-серверу как концепции, здравствуй расползание дизайна во все мыслимые и немыслимые стороны, а потому так делать нежелательно, следовательно разумный выход один — усложнять app-сервер.
Теперь о том, что должен увидеть пользователь.
Если запись захвачена им для просмотора, то хорошо бы её просто изменить, если для редактирования — то он не может увидеть сообщения о том, что запись кем-то изменена, поскольку она не может быть изменена кем-то. Единственный вариант, когда возможна такая ситуация — это при offline-транзакциях (захватили запись на изменение и отключились нафиг), которые сброшены сервером из-за превышения допустимого интервала времени между захватом записи и выполнением транзакции. Но здесь пользователь просто получит сообщение о прекращении транзакции и всё.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, DemAS, Вы писали:
DAS>Здравствуйте, Коваленко Дмитрий, Вы писали:
DAS> DAS> 1. Document и контейнер данных одни на все прилдожение или по экземпляру для каждой сущности (Поставщик, Товар...)
Одни на все приложение.
Твою накладную, или как она там — счет фактура, я бы разложил так:
Document:
Контейнер:
1. Список юр. лиц
2. Список товаров. Каждый товар содержит
- Список цен. Каждая цена это объект
3. Указатель на продавца
4. Указатель на покупателя
5. Табличная часть накладной, каждая запись содержит
- Указатель на цену. Из объекта цены, можно узнать к какому
товару она относится
- Количество
Обрати внимание, что покупатель и продавец могут быть одним и тем же объектом.
Формально, перед тем как грузить что одно, что другого из базы данных,
Document сначало проверяет, что его нет в Списке юр лиц.
То, что в табличной части держаться не сами товары, а их цены, позвляет
один и тот же товар добавить в накладную с разными ценами. Это если, конечно,
цены вводятся отдельно, а не набиваются прямо в накладной :)
Document это совокупность данных, которыми управляет контейнер. У Document'a может быть несколько контейнеров - см. про список копий и транзакцинность изменения Document'a.
КД>>Получение уведомления об изменении данных и их транслирование на уровень пользовательского интерфейса. То есть в Document есть обратная связь с просмотром и редактированием данных юзером.
DAS> Связь двухстороняя ? То есть если пользователь изменил данные на форме, то об этом "узнает" и БД. И если изменились данные в БД(например их изменил другой юзер) то все пользователи узнают про это изменение. Если да, то каким образом реализовано последнее утверждение ?
У нас пока никак. Хотя при записи в базу данных, можно распознать, что после загрузки они изменялись, но на этом мы пока не заморачиваемся.
Вообще, между нами девочками, я тоже когда то был очень озабочен тем, чтобы юзер получал уведомления о том, что его данные кто-то похерил. А сейчас меня это волнует меньше всего — все это отдано на откуп скриптерам, которые пишут логику управления редакторами. Моя стихия — эти редакторы проектировать
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Здравствуйте, DemAS, Вы писали:
DAS>Здравствуйте, c-smile, Вы писали:
DAS> CS>>Какой тип "программы"? CS>>"Программа" это локальная БД — один клиент? (Десктоп) CS>>Или "Программа" это активный клиент пассивного сервера? CS>>Или "Программа" это активный клиент активного сервера? CS>> CS>>А сколько клиентов только читают, а сколько еще и активно пишут?
DAS> На самом деле спрашивал про программу работающую на локальном компе с Access. Ну например так, как Janus.
DAS> Другое дело, что по ходу ответов, меня заинтересовали и другие варианты
В этом случае делай что душе угодно.
Базовые посылки следующие:
Записи в таблицах реляционных БД не есть то же самое что объекты реального мира и классы UI.
Есть некоторое соответсвие. Ну и только.
Попытки построить стройную классовую структуру над всем этим делом обречены на провал.
Разве что в наипростейших случаях.
Более того во взрослых системах очень сильно отличается структура информации (запросов, объектов) на чтение и на запись.
В них же общение клиент сервер выполняется механизмом больше похожим на механизм вызова функций чем на передачу/сохранение объектов.
Я бы порекомендовал тебе сделать две функции типа:
и спрятать за ними весь код физической работы с базой данных.
Т.е. если тебе придется перейти на другую архитектуру БД или в сеть тебе не придется глобально все переделывать.
Заодно такой подход дисциплинирует от размазывания БД по всему приложению.
В UI слое ты можешь делать те классы которые тебе удобны. Но это больше UI oriented классы типа формы редакторы броузеры диалоги.
Реально работать хоть как-то с классами и объектами получается в OODB.
В RDB — забудь. Не забудешь так вспомнишь в очередной раз когда будешь добавлять/убирать колонки в таблицах.
Как я понимаю, эта сладкая парочка представляет собой шлюз к stateless-серверу.
Предлагаю дальнейшее развитие идеи:
1) Проектируем интерфейсы всех сущностей домена. Получаем их определения на языке IDL.
2) С каждой сущностью связываем OID
3) По исходному IDL генерируем IDL для удаленного доступа, следующим образом:
5) Все эти реализации объединяем в одном синглетоне, делая их доступными через QueryInterface. Сам синглетон оформляем как кокласс.
В результате получаем абстрактную реализацию stateless application server.
6) Автоматически генерируем код маршаллинга интерфейсов IRemoteXXX. В результате одним вызовом CoCreateInstanceEx клиент получает через MULTI_QI все, что ему нужно для работы с сервером.
7) Серверу остается реализовать повторно используемый класс m_database, и классы реализации локальных интетфейсов для каждой сущности домена, типа class SomeEntity: public ISomeEntity, и т.п.
Преимущества:
1) Фактически это тоже шлюз, который жрет под себя очень ограниченное количество ресурсов, и обеспечивает такую же производительность и прочие преимущества шлюза.
2) Достаточно спроектировать интерфейсы сущностей, все остальное сгенерируется автоматически по этим интерфейсам.
3) Гораздо проще вносить изменения в интерфейсы.
4) Проект оказывается лучше структурирован, и может вырастать до более крупных размеров без срыва в хаос.
5) Гораздо большая доля кода оказывается повторно используемой.
Недостатки:
1) Нужно единожды написать генератор деклараций удаленных интерфейсов и их реализаций,
2) Нужно единожды написать класс m_database
Думаю, для серьезных проектов приведенные недостатки несущественны.
Преимущества, следующие из недостатков:
1) Имея такой генератор кода, можно запросто избавиться от привязки к DCOM.
очень советую книжку Фаулера. сейчас на в открытом доступе остался только каталог: http://martinfowler.com/eaaCatalog/, но у меня осталась выкачанная бета-версия. надо — могу прислать.
... <<RSDN@Home 1.0 beta 4>> слушаю Porcupine Tree — Metanoia II
Мля, едрить.
Несколько недель разрабатывал архитектуру по подобной теме... С нуля. Сделал, даже некую теорию под такой расклад построил. Получилось практичеки один в один по твоему ответу, в плоть до того что тоже использовал COM-объекты...
И что мне сказало начальство?
"Слишком много философии, мы не занимаемся ресёчем, проще всё должно быть". Сделали "проще" — смотреть код противно.
Есть база данных. В ней есть таблицы. Талицы справочники представляют собой какие-то сущности: например — поставщики, товары, адреса....
Есть программа, которая работает с базой данных. По хорошему, как я понимаю, все эти сущности из БД должны каким-то образом отображаться на классы в программе. То есть у меня в программе должны присутствовать классы Поставщик, Товар, Адрес. Более того, как я понимаю, все изменения в БД должны происходит через методы этих объектов. То есть продажа товара поставщику должна происходить примерно так: Поставщик.Sale(Товар), а уже реализация этого метода должна вызывать измениея в БД.
Как я понимаю, это общепринятая практика ? По моему, если я не ошибаюсь, именно это называется mapping. Это так ?
Где можно почитать про способы, подходы, рекомендации реализации этой идеи.
Здравствуйте, Roman Avramov, Вы писали:
RA>очень советую книжку Фаулера. сейчас на в открытом доступе остался только каталог: RA>http://martinfowler.com/eaaCatalog/, но у меня осталась выкачанная бета-версия. надо — могу прислать.
Понимаю, что здесь про все не расскажешь, но может прокомментируешь вот это:
КД> Чтение-запись в БД не встраивается в сами классы представления данных. Причин очень много, в том числе: КД>
КД> Эффективность КД> Более четкое разделение приложения на подсистемы. КД>
А куда оно встраивается. Писать для этого отдельные классы. Каким образом они будут связаны с классами-сущностями (Поставщик, Товар..) ?
1. Document и контейнер данных одни на все прилдожение или по экземпляру для каждой сущности (Поставщик, Товар...)
КД>Получение уведомления об изменении данных и их транслирование на уровень пользовательского интерфейса. То есть в Document есть обратная связь с просмотром и редактированием данных юзером.
Связь двухстороняя ? То есть если пользователь изменил данные на форме, то об этом "узнает" и БД. И если изменились данные в БД(например их изменил другой юзер) то все пользователи узнают про это изменение. Если да, то каким образом реализовано последнее утверждение ?
Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>У нас пока никак. Хотя при записи в базу данных, можно распознать, что после загрузки они изменялись, но на этом мы пока не заморачиваемся.
Ну вот те раз. Начали за здравие а закончили... признанием в любви к stateless-модели.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, DemAS, Вы писали:
DAS> Есть база данных. В ней есть таблицы. Талицы справочники представляют собой какие-то сущности: например — поставщики, товары, адреса.... DAS> Есть программа, которая работает с базой данных. По хорошему, как я понимаю, все эти сущности из БД должны каким-то образом отображаться на классы в программе. То есть у меня в программе должны присутствовать классы Поставщик, Товар, Адрес. Более того, как я понимаю, все изменения в БД должны происходит через методы этих объектов. То есть продажа товара поставщику должна происходить примерно так: Поставщик.Sale(Товар), а уже реализация этого метода должна вызывать измениея в БД. DAS> Как я понимаю, это общепринятая практика ? По моему, если я не ошибаюсь, именно это называется mapping. Это так ? DAS> Где можно почитать про способы, подходы, рекомендации реализации этой идеи. DAS>
Эй! Вы чего в самом деле?
Какой тип "программы"?
"Программа" это локальная БД — один клиент? (Десктоп)
Или "Программа" это активный клиент пассивного сервера?
Или "Программа" это активный клиент активного сервера?
А сколько клиентов только читают, а сколько еще и активно пишут?
И т.д.
А уж потом можно говорить про паттерны, объекты или фуекции, statefull, stateless-but-timestaps или stateless-fire-n-forget и ...
Здравствуйте, Геннадий Васильев, Вы писали:
КД>>У нас пока никак. Хотя при записи в базу данных, можно распознать, что после загрузки они изменялись, но на этом мы пока не заморачиваемся.
ГВ>Ну вот те раз. Начали за здравие а закончили... признанием в любви к stateless-модели.
Вы чего при детях выражаетесь ?
Двунаправленный обмен данных подразумевает наличие сервера приложений. По крайней мере, если сервером базы данных является InterBase, то из него app-сервер не сделаешь. А я трезво оцениваю свои возможности и возможности нашей команды — мы такую архитектуру ПО просто не потянем. А может нам просто нужен новый архитектор системы
А с другой стороны, что именно должен увидеть юзер, когда редактируемые данные изменились? Предупреждение в строке состояния ? Дык, как я уже сказал, это можно отложить до момента записи и сравнить дату модификации, которую мы прочитали при загрузке, с той, которую мы увидим на момент записи. Во время записи — мы её обновим.
Если я правильно все понял, то лучше вынести это обсуждение в отдельную ветку — чукча будет читателем
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
CS>Какой тип "программы"? CS>"Программа" это локальная БД — один клиент? (Десктоп) CS>Или "Программа" это активный клиент пассивного сервера? CS>Или "Программа" это активный клиент активного сервера? CS> CS>А сколько клиентов только читают, а сколько еще и активно пишут?
На самом деле спрашивал про программу работающую на локальном компе с Access. Ну например так, как Janus.
Другое дело, что по ходу ответов, меня заинтересовали и другие варианты
Здравствуйте, Roman Avramov, Вы писали:
RA>очень советую книжку Фаулера. сейчас на в открытом доступе остался только каталог: RA>http://martinfowler.com/eaaCatalog/, но у меня осталась выкачанная бета-версия. надо — могу прислать.
А вот бы и на lucker@csl.minsk.by получить копию
Здравствуйте, DemAS, Вы писали:
DAS> Есть база данных. В ней есть таблицы. Талицы справочники представляют собой какие-то сущности: например — поставщики, товары, адреса.... DAS> Есть программа, которая работает с базой данных. По хорошему, как я понимаю, все эти сущности из БД должны каким-то образом отображаться на классы в программе. То есть у меня в программе должны присутствовать классы Поставщик, Товар, Адрес. Более того, как я понимаю, все изменения в БД должны происходит через методы этих объектов. То есть продажа товара поставщику должна происходить примерно так: Поставщик.Sale(Товар), а уже реализация этого метода должна вызывать измениея в БД. DAS> Как я понимаю, это общепринятая практика ? По моему, если я не ошибаюсь, именно это называется mapping. Это так ?
Да.
DAS> Где можно почитать про способы, подходы, рекомендации реализации этой идеи.
Здравствуйте, Геннадий Васильев, Вы писали:
ГВ>Это всё верно, но только для относительно простых случаев. Есть ещё несколько соображений. Например, юзер А тратит много времени на обновление какой-то записи ...
У нас понятия запись (если смотреть со стороны юзера) вообще не существует, так что переходим к составным объектам (другой вариант)
ГВ>Другой вариант. Запись (вернее — логический обновляемый объект) состоит из тучи мелких связанных записей, которые могут обновляться независимо (допустим — через drill-down навигацию), притом обновление одной из них может привести к недопустимости обновления агрегата, который при такой схеме и знать не будет о том, что какая-то его часть изменилась. Здесь вроде бы, логически, выход в том, чтобы вынести всю логику контроля целостности на... сервер БД и привет app-серверу как концепции, здравствуй расползание дизайна во все мыслимые и немыслимые стороны, а потому так делать нежелательно, следовательно разумный выход один — усложнять app-сервер.
Один из способов, которые могут применить наши скриптеры (и применяют относительно документов), это использовать информацию о владении документом — из документооборота. Владелец может все. Другие (в зависимости от своих прав) этот объект либо совсем не смогут загрузить, либо загрузят его в режиме только на чтение.
Насчет выноса логики на сервер БД — это просто не реально. Особенно для IB. Мы не оперируем понятиями запись — ну если только речь не идет про таблицу типов. Значит проверить достоверность данных можно только имея доступ к объекту целиком (типа несколько записей). Как например, передать в хранимую процедуру составной документ, чтобы она его проверила и сохранила, я лично не представляю
App-сервер, это конечно позволит сделать, но.
App-сервер вытаскивает данные (+ проверка прав и все такое)
Упаковывает их в промежуточный формат (пусть XML) и передает клиенту
Клиент получает пакет, распаковывает, выводит на экран
Один черт, на клиенте должен крутится скрипт, который будет контролировать сам процесс редактирования документа — какую-то его часть можно редактировать, какую-то нет. Что сейчас, в принципе и делается.
При нажатии на сохранить, клиент упаковывает запись, передает на app-сервер
App-сервер распаковывает, проверяет, и пишет в базу данных.
Вообще, конечно мысль интересная. Особенно если логику app-сервера прописывать на интерпретируемом языке, но точно говорю — нам это пока не по-зубам. По крайней мере ближайший год-полтора это точно. Мы сейчас закручиваем гайки, которые не дают пользователям "шалить" в базе данных
ГВ>Теперь о том, что должен увидеть пользователь.
ГВ>Если запись захвачена им для просмотора, то хорошо бы её просто изменить, если для редактирования — то он не может увидеть сообщения о том, что запись кем-то изменена, поскольку она не может быть изменена кем-то. Единственный вариант, когда возможна такая ситуация — это при offline-транзакциях (захватили запись на изменение и отключились нафиг), которые сброшены сервером из-за превышения допустимого интервала времени между захватом записи и выполнением транзакции. Но здесь пользователь просто получит сообщение о прекращении транзакции и всё.
У нас минимизированы периоды активных транзакций. То есть загрузка/запись данных делается в разных "коротких" транзакциях, продолжительность которых пропорциональна объему данных. Это из-за специфики IB, который при длинных транзакциях, начинает накапливать мусор в базе данных.
А вообще, Генадий, будет у нас на Кол..., то есть Липецке — заходите в гости и все увидите своими глазами
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>Один из способов, которые могут применить наши скриптеры (и применяют относительно документов), это использовать информацию о владении документом — из документооборота. Владелец может все. Другие (в зависимости от своих прав) этот объект либо совсем не смогут загрузить, либо загрузят его в режиме только на чтение.
Т.е., скрипт проверяет содержимое полей объекта на предмет соответствия их каким-то условиям и в зависимости от этих условий выполняет те или иные действия. Так?
КД>Насчет выноса логики на сервер БД — это просто не реально. Особенно для IB. Мы не оперируем понятиями запись — ну если только речь не идет про таблицу типов. Значит проверить достоверность данных можно только имея доступ к объекту целиком (типа несколько записей). Как например, передать в хранимую процедуру составной документ, чтобы она его проверила и сохранила, я лично не представляю
Ну, к слову, можно передать ключ временной копии документа, хранящейся в БД.
КД>App-сервер, это конечно позволит сделать, но. КД>
[...] КД>Один черт, на клиенте должен крутится скрипт, который будет контролировать сам процесс редактирования документа — какую-то его часть можно редактировать, какую-то нет. Что сейчас, в принципе и делается.
Ну вот это тоже я и имел ввиду под словами "расползание дизайна". Часть логики у вас реализована в термиах App-сервера, часть — в терминах скриптов.
[...] КД>
КД>Вообще, конечно мысль интересная. Особенно если логику app-сервера прописывать на интерпретируемом языке, но точно говорю — нам это пока не по-зубам. По крайней мере ближайший год-полтора это точно. Мы сейчас закручиваем гайки, которые не дают пользователям "шалить" в базе данных
Ну, тебе виднее...
КД>У нас минимизированы периоды активных транзакций. То есть загрузка/запись данных делается в разных "коротких" транзакциях, продолжительность которых пропорциональна объему данных. Это из-за специфики IB, который при длинных транзакциях, начинает накапливать мусор в базе данных.
Т.е., столкновение транзакций у вас не просто вероятно, а очень вероятно... Вероятность, впрочем, несколько снижается за счёт организационных мер, применяемых к пользователям. Не фонтан... ИМХО
КД>А вообще, Генадий, будет у нас на Кол..., то есть Липецке — заходите в гости и все увидите своими глазами
Нет уж, лучше вы — к нам. (c)
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, Геннадий Васильев, Вы писали:
КД>>Один из способов, которые могут применить наши скриптеры (и применяют относительно документов), это
ГВ>Т.е., скрипт проверяет содержимое полей объекта на предмет соответствия их каким-то условиям и в зависимости от этих условий выполняет те или иные действия. Так?
Точно.
КД>>Насчет выноса логики на сервер БД — это просто не реально. Особенно для IB. Мы не оперируем
ГВ>Ну, к слову, можно передать ключ временной копии документа, хранящейся в БД.
О нет. Это же два раза писать в базу, а потом еще и копию удалять. Мне кажется это накладно
KD>Один черт, на клиенте должен крутится скрипт, который будет контролировать сам процесс редактирования документа — какую-то его часть можно редактировать, какую-то нет. Что сейчас, в принципе и делается. ГВ>Ну вот это тоже я и имел ввиду под словами "расползание дизайна". Часть логики у вас реализована в термиах App-сервера, часть — в терминах скриптов.
По другому пока не получается. А может просто нужно это все как-то иначе назвать . Хотелось бы чтобы название было цензурным
ГВ>Т.е., столкновение транзакций у вас не просто вероятно, а очень вероятно... Вероятность, впрочем, несколько снижается за счёт организационных мер, применяемых к пользователям. Не фонтан... ИМХО
Мне кажется, что опасность конфликтов между пользователями очень преувеличена. По крайней мере за пол-года эксплуатации у нас не было не одной подобной проблемы. Хотя это не значит что у нас все пущено на самотек
А используя длинные транзакциями, мы бы точно огребли кучу непрятностей.
ГВ>Нет уж, лучше вы — к нам. (c)
Как только — так сразу
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Здравствуйте, DemAS, Вы писали:
DAS> Есть база данных. В ней есть таблицы. Талицы справочники представляют собой какие-то сущности: например — поставщики, товары, адреса.... DAS> Есть программа, которая работает с базой данных. По хорошему, как я понимаю, все эти сущности из БД должны каким-то образом отображаться на классы в программе. То есть у меня в программе должны присутствовать классы Поставщик, Товар, Адрес. Более того, как я понимаю, все изменения в БД должны происходит через методы этих объектов. То есть продажа товара поставщику должна происходить примерно так: Поставщик.Sale(Товар), а уже реализация этого метода должна вызывать измениея в БД. DAS> Как я понимаю, это общепринятая практика ? По моему, если я не ошибаюсь, именно это называется mapping. Это так ? DAS> Где можно почитать про способы, подходы, рекомендации реализации этой идеи.
Посмотрите СУБД Cache www.cache.ru. Эта объектно-реляционная СУБД умеет отображать свои таблицы на C++ классы автоматически. И вообще много чего еще умеет полезного.
Здравствуйте, DemAS, Вы писали:
DAS> Есть программа, которая работает с базой данных. По хорошему, как я понимаю, все эти сущности из БД должны каким-то образом отображаться на классы в программе.
Я однажды написал програмку, которая коннектилась к схеме Оракловой СУБД, считывала все метаданные и генерировала исходный код (на Delphi) классов всех объектов со всеми взаимными ссылками между объектами. Впридачу генерила классы соответствующие таблицам и умеющие загружать свои данные из БД, и даже умеющая сортировать их по всем полям; и еще рисовать свое содержимое в TStringGrid-ах. Запускаешь такую прогу, получаешь исходник. Компилишь исходник получаешь программу которая может законнектиться к СУБД и выкачать из нее все данные в виде объектов со всеми взаимными ссылками и показать их все в стринг-гридах с возможностью отсортировать по разным столбцам. Потом я приостановил работу над этой прогой — у начальства она не вызвала приступа энтузиазма, мне поручили заниматься другими вещами.
Здравствуйте, DemAS, Вы писали:
DAS> Есть база данных. В ней есть таблицы. Талицы справочники представляют собой какие-то сущности: например — поставщики, товары, адреса.... DAS> Есть программа, которая работает с базой данных. По хорошему, как я понимаю, все эти сущности из БД должны каким-то образом отображаться на классы в программе. То есть у меня в программе должны присутствовать классы Поставщик, Товар, Адрес. Более того, как я понимаю, все изменения в БД должны происходит через методы этих объектов. То есть продажа товара поставщику должна происходить примерно так: Поставщик.Sale(Товар), а уже реализация этого метода должна вызывать измениея в БД. DAS> Как я понимаю, это общепринятая практика ? По моему, если я не ошибаюсь, именно это называется mapping. Это так ? DAS> Где можно почитать про способы, подходы, рекомендации реализации этой идеи.
Здравствуйте, DemAS, Вы писали:
DAS> Есть база данных. В ней есть таблицы. Талицы справочники представляют собой какие-то сущности: например — поставщики, товары, адреса.... DAS> Есть программа, которая работает с базой данных. По хорошему, как я понимаю, все эти сущности из БД должны каким-то образом отображаться на классы в программе. То есть у меня в программе должны присутствовать классы Поставщик, Товар, Адрес. Более того, как я понимаю, все изменения в БД должны происходит через методы этих объектов. То есть продажа товара поставщику должна происходить примерно так: Поставщик.Sale(Товар), а уже реализация этого метода должна вызывать измениея в БД. DAS> Как я понимаю, это общепринятая практика ? По моему, если я не ошибаюсь, именно это называется mapping. Это так ? DAS> Где можно почитать про способы, подходы, рекомендации реализации этой идеи.
Мартин Фаулер "Архитектура корпоративных приложений"
Издательский дом "Вильямс" 2004
Подробно описаны типовые решения задач проектирования корпоративных приложений.
Здравствуйте, Roman Avramov, Вы писали:
RA>очень советую книжку Фаулера. сейчас на в открытом доступе остался только каталог: RA>http://martinfowler.com/eaaCatalog/, но у меня осталась выкачанная бета-версия. надо — могу прислать.
Здравствуйте, Roman Avramov, Вы писали:
RA>очень советую книжку Фаулера. сейчас на в открытом доступе остался только каталог: RA>http://martinfowler.com/eaaCatalog/, но у меня осталась выкачанная бета-версия. надо — могу прислать.
Здравствуйте, KBH, Вы писали:
KBH>Здравствуйте, Roman Avramov, Вы писали:
RA>>очень советую книжку Фаулера. сейчас на в открытом доступе остался только каталог: RA>>http://martinfowler.com/eaaCatalog/, но у меня осталась выкачанная бета-версия. надо — могу прислать.
KBH>И мне пожалуйста, если несложно. Заранее спасибо.
На Соколе в доме книги видел несколько дней назад. Если что..
Здравствуйте, Roman Avramov, Вы писали:
RA>очень советую книжку Фаулера. сейчас на в открытом доступе остался только каталог: RA>http://martinfowler.com/eaaCatalog/, но у меня осталась выкачанная бета-версия. надо — могу прислать.
Здравствуйте, KBH, Вы писали:
KBH>Здравствуйте, g_i, Вы писали:
g_i>>На Соколе в доме книги видел несколько дней назад. Если что..
KBH>Я в Краснодаре живу, если что.
Мдя. Ну там и воздух чище и климат мягше зато . Можно заказать доставку, наверное, с какого-нить интернет магазина. Только дорого выйдет (сама книжень недешевая + тяжелая, зараза — почта вроде по весу стоимость доставки определяет ).
Здравствуйте, g_i, Вы писали:
g_i>Мдя. Ну там и воздух чище и климат мягше зато . Можно заказать доставку, наверное, с какого-нить интернет магазина. Только дорого выйдет (сама книжень недешевая + тяжелая, зараза — почта вроде по весу стоимость доставки определяет ).
Здравствуйте, Roman Avramov, Вы писали:
RA>очень советую книжку Фаулера. сейчас на в открытом доступе остался только каталог: RA>http://martinfowler.com/eaaCatalog/, но у меня осталась выкачанная бета-версия. надо — могу прислать.
DAS> Есть база данных. В ней есть таблицы. Талицы справочники представляют собой какие-то сущности: например — поставщики, товары, адреса.... DAS> Есть программа, которая работает с базой данных. По хорошему, как я понимаю, все эти сущности из БД должны каким-то образом отображаться на классы в программе.
Здравствуйте, Roman Avramov, Вы писали:
RA>очень советую книжку Фаулера. сейчас на в открытом доступе остался только каталог: RA>http://martinfowler.com/eaaCatalog/, но у меня осталась выкачанная бета-версия. надо — могу прислать.
Здравствуйте, DemAS, Вы писали:
DAS> Как я понимаю, это общепринятая практика ? По моему, если я не ошибаюсь, именно это называется mapping. Это так ?
Почти.
DAS> Где можно почитать про способы, подходы, рекомендации реализации этой идеи.
Примеры и исходники можно взять здесь: Hibernate или NHibernate
или .NET Data Access Objects
Здравствуйте, iZEN, Вы писали:
ZEN>Здравствуйте, DemAS, Вы писали:
DAS>> Есть база данных. В ней есть таблицы. Талицы справочники представляют собой какие-то сущности: например — поставщики, товары, адреса.... DAS>> Есть программа, которая работает с базой данных. По хорошему, как я понимаю, все эти сущности из БД должны каким-то образом отображаться на классы в программе. То есть у меня в программе должны присутствовать классы Поставщик, Товар, Адрес. Более того, как я понимаю, все изменения в БД должны происходит через методы этих объектов. То есть продажа товара поставщику должна происходить примерно так: Поставщик.Sale(Товар), а уже реализация этого метода должна вызывать измениея в БД. DAS>> Как я понимаю, это общепринятая практика ? По моему, если я не ошибаюсь, именно это называется mapping. Это так ?
ZEN>Да.
А делают, что то типа такого?: Сущности — только класс со свойствами, и еще один слой — слой логики где происходит манипуляция с этими сущностями. Или этот подход не верен?
типа:
class Person
{
public int ID;
public string FullName;
}
class PersonBusinesLogic
{
public bool CheckCredit(Person p)
{
///
}
}
DAS>> Где можно почитать про способы, подходы, рекомендации реализации этой идеи.
ZEN>Так Java2 Enterprise Edition, в частности технология EJB (CMP, BMP, etc.), именно это имеет в своей основе. ZEN>http://java.sun.com/products/ejb/docs.html
Здравствуйте, lextasy, Вы писали:
L>Предлагаю дальнейшее развитие идеи:
L>1) Проектируем интерфейсы всех сущностей домена. Получаем их определения на языке IDL. L>2) С каждой сущностью связываем OID L>3) По исходному IDL генерируем IDL для удаленного доступа, следующим образом:
То что ты предлагаешь называется DCOM.
Это я к тому что оно как бы уже и так есть.
Надо просто зарегистрировать твою classlib как out-of-process-remote.
Здравствуйте, <Аноним>, Вы писали: А>А делают, что то типа такого?: Сущности — только класс со свойствами, и еще один слой — слой логики где происходит манипуляция с этими сущностями. Или этот подход не верен?
А, пардон, зачем? Чтобы побольше было мест, где надо изменения вносить при выявлении новых требований?
... << RSDN@Home 1.1.4 @@subversion >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, c-smile, Вы писали:
CS>Здравствуйте, lextasy, Вы писали:
L>>Предлагаю дальнейшее развитие идеи:
L>>1) Проектируем интерфейсы всех сущностей домена. Получаем их определения на языке IDL. L>>2) С каждой сущностью связываем OID L>>3) По исходному IDL генерируем IDL для удаленного доступа, следующим образом:
CS>То что ты предлагаешь называется DCOM. CS>Это я к тому что оно как бы уже и так есть. CS>Надо просто зарегистрировать твою classlib как out-of-process-remote.
CS>То что есть — точно. А вот детали уже не упомню.
Если использовать DCOM как есть, т.е. "просто зарегистрировать твою classlib как out-of-process-remote", то получим такие траблы, из-за которых, собственно, DCOM и не прижился (помимо всего прочего, конечно):
1) Клиенту придется на каждый объект БД инстанцировать proxy-объект, а серверу — соответствующий stub. Это не только на порядок уменьшит отзывчивость сервера, но и сильно ударит по ресурсам обоих машин.
2) Будут огромные тормозняки из-за того, что интерфейсы, спроектированные для непосредственного (in-process) доступа, непригодны для удаленного доступа. Для удаленного доступа нужна гранулярность запросов побольше, а частота — поменьше.
3) Про stateless — сервер можно будет забыть, иначе у клиентов начнутся проблемы типа E_DISCONNECT при попытке доступа к уже удаленным на сервере объектам. Да и CoDisconnectObject() на каждый пук вызывать просто по-человечески жаба давит.
4) Управление транзакциями невозможно будет полностью инкапсулировать на сервере — с учетом предыдущих проблем это значит полный каюк, если клиентов планируется много.
Хотя предложенная реализация базируется на DCOM, она не сводится просто к использованию DCOM. Это именно ШЛЮЗ, предоставляющий ФИКСИРОВАННОЕ количество интерфейсов, ОТНЮДЬ НЕ ТОЖДЕСТВЕННЫХ тем интерфейсам, которые определениы в исходной библиотеке типов, используемой сервером.
Просто это, так скажем, более жестко типизированный шлюз, т.е. использует более детерминированный протокол и соответственно приводит к меньшему количеству ошибок, обусловленных нарушением протокола. Думаю, это важно, т.к. в процессе разработки системы протокол шлюза эволюционирует, и хотелось бы чтобы при этом компилятор помогал выявлять код, требующий обновления.
Re[4]: Отображение БД на классы
От:
Аноним
Дата:
15.09.04 14:26
Оценка:
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, <Аноним>, Вы писали: А>>А делают, что то типа такого?: Сущности — только класс со свойствами, и еще один слой — слой логики где происходит манипуляция с этими сущностями. Или этот подход не верен? S>А, пардон, зачем? Чтобы побольше было мест, где надо изменения вносить при выявлении новых требований?
А если веб сервисы? Возвращать прямо BusinessComponent?
Извиняюсь, но вынужден поднять этот давний вопрос.
CS>Я бы порекомендовал тебе сделать две функции типа:
CS>collection read(id request, collection parameters) CS>collection write(id request, collection parameters)
CS>и спрятать за ними весь код физической работы с базой данных. CS>Т.е. если тебе придется перейти на другую архитектуру БД или в сеть тебе не придется глобально все переделывать. CS>Заодно такой подход дисциплинирует от размазывания БД по всему приложению.
Что в данном случае представляет собой collection parameters? Это коллекция (ArrayList) неких объектов, в которых кроме самого значения параметра долна храниться информация о его типе?
То есть у меня есть такой код.
ArrayList Write(string query, ArrayList parameters)
{
FbConnection connection = dbManager.GetConnection();
connection.Open();
FbCommand command = new FbCommand(query, connection);
// from here
command.Parameters.Add("@parentid", FbDbType.Integer).Value = task.parent_id;
command.Parameters.Add("@name", FbDbType.VarChar).Value = task.name;
command.Parameters.Add("@description", FbDbType.VarChar).Value = task.description;
command.Parameters.Add("@category", FbDbType.Integer).Value = 4;
// to here
command.ExecuteNonQuery();
connection.Close();
}
Какова долдна быть структура parametrs, чтобы я смог динамически извлечь эти параметры и заменить код между комментариями?