Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.09.26;
Скачать: CL | DM;

Вниз

Реализация БД-приложений   Найти похожие ветки 

 
GRAND25 ©   (2004-09-06 17:02) [0]

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

Итак, суть самой задачи. Имеется документ, являющий собой приходный ордер на склад. Документ может содержать в себе неограниченное количество единиц складского учета, относящихся к нему. Задача: обеспечить ввод и редактирование приходных ордеров и объектов складского учета. Просто? Вроде бы да.

1 подход. В БД создается таблица приходных ордеров и таблица объектов учета. Во второй таблице есть поле, являющееся внешним ключом на первую. Классическая связь один-ко-многим. В клиентском приложении есть два датасета, связанные между собой соотношением Master-Detail. Форма клиентского приложения, которая будет обеспечивать ввод/просмотр/редактирование записей, состоит из элементов управления, привязанных (bounded) к конкретным полям базы данных. Грид внизу формы позволяет выбрать нужную запись для редактирования. Пользователь работает с базой данных напрямую, имея возможность ввести новую запись или отредактировать уже имеющуюся.

2 подход. В клиентском приложении разрабатываются классы, являющие собой приходный ордер и объект учета. Класс приходного ордера содержит в себе коллекцию (collection) из объектов учета, относящихся к нему. Форма клиентского приложения, которая будет обеспечивать ввод/просмотр/редактирование записей, состоит из элементов управления, не привязанных (unbounded) к конкретным полям базы данных. Грид внизу формы показывает уже введенные объекты учета. В процессе ввода клиентское приложение в памяти локальной рабочей станции формирует и хранит приходный ордер с коллекцией его объектов учета. В разработанных классах имеются методы InsertToDB, которые физически добавляют новую запись в соответствующую таблицу. По нажатию кнопки "Сохранить" происходит запись введенных объектов из памяти в базу данных (сначала приходный ордер, а потом циклически по всей коллекции все объекты складского учета).

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

Заранее благодарен.


 
Ega23 ©   (2004-09-06 17:10) [1]

Что-то я второй способ не до конца понял.  Это что, у тебя всего один клиент?

По вопросу: в первом продходе предлагаешь редактирование напрямую в гриде?


 
GRAND25 ©   (2004-09-06 17:14) [2]


> Что-то я второй способ не до конца понял.  Это что, у тебя
> всего один клиент?


В каком смысле один? Клиентское приложение одно, работающих экземпляров несколько.


> По вопросу: в первом продходе предлагаешь редактирование
> напрямую в гриде?


Да, грид связан со своим источником данных. Редактирование в гриде автоматически означает редактирование в таблице БД (разумеется, после вызова метода Post).


 
Игорь Шевченко ©   (2004-09-06 17:15) [3]


> Какой из этих подходов вы считаете наиболее рациональным,
> современным и правильным?


Второй.


 
Sergey_Masloff   (2004-09-06 17:17) [4]

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


 
Ega23 ©   (2004-09-06 17:19) [5]

Вообще-то ни тот, ни другой...  :о)
В смысле, не считаю правильным или неправильным, а просто симпатизирую к третьему....  :о)


 
Sergey_Masloff   (2004-09-06 17:20) [6]

Блин, тема интересная. Давно хотел по этому поводу с народом пообщаться - но только с теми кто шишек уже понабивал.


 
GRAND25 ©   (2004-09-06 17:23) [7]

2 Игорь Шевченко: обосновать есть чем?


 
Sergey_Masloff   (2004-09-06 17:26) [8]

Кроме того второй подход сложнее при работе с коллекциями - например в счете фигурируют документы каждый из которых свой сложный объект. Манипулируя датасетом а не объектом коллекции очень просто (потому что все написано давно) мгновенно менять состав полей - ну допустим кроме номера документа я захотел видеть еще пару других реквизитов - переписывай коллекцию ;-) А не одну строчку SQL.
 Проблемы с LazyLoad когда один объект может возникать как дочерний ко многим - приходится реализовать счетчик ссылок или его аналог что реализуемо но трудоемко читай потенциально глючно. И др.
 Но все же окончательно эту идею я не похоронил, просто продумываю "новый виток". А так пока шишек больше чем плодов (хотя проект успешный вполне - но традиционными технологиями я б его быстрей сделал).


 
by ©   (2004-09-06 17:29) [9]

Как написано у Фаулера, в его Архитектуре корпоративных приложений, есть три метода реализации корпоративных приложений (за дословность не ручаюсь, книга дома, может кто подправит)
1) процедурный, все делаем через процедуры/функции на клиенте или структурный
2) все представляем через классы
3) все представляем через работу с набором данных.
Он говорит что наиболее прогресивен метод определения предметной области через классы и их взаимодействие. Но для языков программирования которые поддерживают концепцию dataset/recordset (Delphi, C#) и емеют средства для работы с ней (grid, dbaware edits) очень подходит и модель работы с набором данных


 
by ©   (2004-09-06 17:35) [10]

Но при работе только через объекты очень много нужно писать. Кода больше чем при работе с датасетом. Мой первый проект в котором я участвовал был полностью построен на идеологии объектов, без DBEdit-ов, и писалось кода довольно много. При дальнейшей работе, когда в других проектах я сам стал писать базовые класы я перешел к идеологии датасета, так как таким образом можно было писать с меньшими затратами и использовать то что уже реализовано в среде разработки. Счас, после прочтения книг, опять на распутье.


 
Игорь Шевченко ©   (2004-09-06 17:38) [11]

GRAND25 ©   (06.09.04 17:23) [7]


> 2 Игорь Шевченко: обосновать есть чем?


Фаулер. Архитектура корпоративных приложений.
Фаулер. Рефакторинг. Раздел "Дублировние видимого кода".

Sergey_Masloff   (06.09.04 17:17) [4]


> п. 2 требует на порядок больших усилий как на разработку
> так и на поддержку. Хотя в теории более "красив".


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


 
Iconka ©   (2004-09-06 17:42) [12]


> Фаулер. Архитектура корпоративных приложений.
> Фаулер. Рефакторинг. Раздел "Дублировние видимого кода".

В электронном виде есть?


 
GRAND25 ©   (2004-09-06 17:46) [13]

Неясно, что обеспечит гибкость проекта при втором подходе?


> я захотел видеть еще пару других реквизитов - переписывай
> коллекцию ;-) А не одну строчку SQL.


Вот золотые слова! Бизнес-логика где будет? Правильно, на клиенте. Тогда неясно, зачем и кому нужна будет вся мощь SQL-сервера с его триггерами и SP? И потом, полагаться не на аппаратное обеспечение одного сервера, а множества воркстейшенов?


 
by ©   (2004-09-06 17:47) [14]

В электронном виде есть?

я не нашел, пришлось покупать
правда Refactoring на английском нашел


 
GRAND25 ©   (2004-09-06 17:50) [15]

Игорь, Фаулер - это все хорошо, свое мнение на данный счет у тебя на чем базируется? Опытом поделиться можешь, как ты разрабатывал приложения, пользуясь подходом №2, и какой неизгладимый след в твоей душе этот подход оставил?


 
Sergey_Masloff   (2004-09-06 17:51) [16]

Sergey_Masloff   (06.09.04 17:17) [4]

>Да и на практике тоже неплох, по крайней мере, своей гибкостью, >в ряде случаев.
Да я и не спорю. Но очень много писать... и очень одинакового. Примеры Фаулера пока не очень убеждают - все же он видимо больше знаком с Java где все не совсем так. Тем более он явно указывает что в ряде случаев NET датасет вполне применимое решение.
 
И с гридами. Все же грид + навигатор настолько удобная и привычная пользователям вещь... Соответственно на ее эмуляцию в случае объектов тоже время (а время - деньги). Или объект - коллекция  как обертка над датасетом - тоже что-то не очень нравится.

Есть еще много сложных и спорных моментов. Вобщем, то ли руки мне еще править и править но пока полного консенсуса с чисто объектным подходом не получилось у меня.


 
by ©   (2004-09-06 17:51) [17]

Ну использовать stored proc можно и при использовании объектов, но тот же Файлер против этого, растаскивание бизнес логики по нескольким местам, да и не все реализуемо через язык SP


 
Игорь Шевченко ©   (2004-09-06 17:53) [18]

GRAND25 ©   (06.09.04 17:50) [15]


> свое мнение на данный счет у тебя на чем базируется?


На опыте и прочтении того же Фаулера.


> Опытом поделиться можешь, как ты разрабатывал приложения,
> пользуясь подходом №2, и какой неизгладимый след в твоей
> душе этот подход оставил?


А ты почитай Фаулера, он довольно подробно все излагает...


 
Игорь Шевченко ©   (2004-09-06 17:54) [19]

Sergey_Masloff   (06.09.04 17:51) [16]


> Или объект - коллекция  как обертка над датасетом - тоже
> что-то не очень нравится.


А чем не нравится ?


 
Sergey_Masloff   (2004-09-06 17:57) [20]

by ©   (06.09.04 17:51) [17]
>Ну использовать stored proc можно и при использовании объектов, >но тот же Файлер против этого, растаскивание бизнес логики по >нескольким местам, да и не все реализуемо через язык SP
Ну вот тут он однозначно не прав. На языке SP можно реализовать практически все. И зачастую гораздо проще чем на клиенте - потому что в КОРПОРАТИВНЫХ системах очень часты случаи когда для определенных действий требуются множество данных из базы за которыми лезть из клиента очень накладно и код хранимой процедуры на PL-SQL в 20 строчек превращается в 400 строк клиентского кода с десятком обращений к серверу.


 
GRAND25 ©   (2004-09-06 18:00) [21]


> На опыте и прочтении того же Фаулера.



> А ты почитай Фаулера, он довольно подробно все излагает...


Веско, спасибо!


 
by ©   (2004-09-06 18:01) [22]

Для себя я пока избрал подход слияния объекта и датасета. Например, у меня есть базовый класс TBaseForm, от него наследник TListForm, который и содержит грид, кнопки и пр. Его наследники, например TListGoods (справочник товаров) и есть объекты моей системы, у них есть методы типа Refresh, makeSQL, DeleteRec и пр. Это объектная часть. А часть датасета - это то, метод makeSQL или DeleteRec работает уже непоследственно и датасетом и применяет DBAware компоненты.


 
by ©   (2004-09-06 18:04) [23]

Sergey_Masloff   (06.09.04 17:57) PL-SQL в 20 строчек превращается в 400 строк клиентского кода с десятком обращений к серверу

это да, но как быть в случаях когда нужно работать с несколькими источниками данных, когда основная БД на Firebird, а данные в неё заливаются из dbf, текстовых файлов, и в этой заливке много бизнес логики. Тут одними SP не обойдешься


 
}|{yk ©   (2004-09-06 18:07) [24]

Кстати, об этом я написал статью, скоро появится на delphimaster.ru


 
Sergey_Masloff   (2004-09-06 18:10) [25]

by ©   (06.09.04 18:01) [22]
То что ты описываешь это то как у меня текущий проект. Его я объектным не называю и вот по какой причине - у меня была мечта (как у М.Л. Кинга) все же отделить объекты от их визуального представления. Чтобы объект ничего не знал о формах которые его отображают (да и форм бы не было допустим).
 Кроме теоретической пользы я преследовал практическую цель - мне нужно было дать вовне мой объект внешнему приложению которое использовало бы его для работы с нашей базой. Мне это удалось вобщем-то но затраты времени на реализацию оказались очень большими. Правда одной из причин было то что многие операции с данными делались в базе, то есть был маппинг базы на объекты двойной - при определенных действиях состояние объекта в БАЗЕ менялось приходилось маппить все это на объект а потом и на внешнее представление.


 
GRAND25 ©   (2004-09-06 18:13) [26]

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


 
Sergey_Masloff   (2004-09-06 18:14) [27]

Игорь Шевченко ©   (06.09.04 17:54) [19]
>> Или объект - коллекция  как обертка над датасетом - тоже
>> что-то не очень нравится.

>А чем не нравится ?

Ну а тогда чем форма не объект? На нее датасеты датаконтролы и датасорсы - вот и получили объектный подход ;-)

Ну это я утрирую. Я думал о клиент датасете как о элементе реализации объектов коллекций. Пока без практических выводов. К сожалению катастрофически не хватает времени - текучка душит :(((


 
by ©   (2004-09-06 18:18) [28]

Sergey_Masloff   (06.09.04 18:10)

мечта такая у меня есть и сейчас, заманчиво реализовать Model View Controler и прочее. Но из реалий я вижу что очень много нужно писать, намного больше чем при модели через датасет, и это сдерживает.


 
GRAND25 ©   (2004-09-06 18:19) [29]

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


 
Sergey_Masloff   (2004-09-06 18:22) [30]

GRAND25 ©   (06.09.04 18:19) [29]
>Далее. Интересно было бы рассмотреть, какое приложение >производительнее: то, которое по ходу своей работы вставляет >записи в таблицу БД физически или то, которое хранит все в >памяти, а потом оптом сливает в базу записей эдак 70?
70 записей? Без разницы если конечно не на диалапе это все происходит. Единственно что может быть выгоднее - длина вставляющей транзакции. Но это не всегда критично.


 
Игорь Шевченко ©   (2004-09-06 18:23) [31]

Sergey_Masloff   (06.09.04 18:14) [27]

Я почему спросил, чем не нравится, потому что мы испытывали сомнения при подобном же подходе. И от грида в ряде случаев не хочется отказываться и честь соблюсть. Кстати, в приснопамятной программе МАРС такой подход использовался, с ClientDataSet для работы с гридом, я бы не сказал, что это сильно усложнило работу.


 
Sergey_Masloff   (2004-09-06 18:34) [32]

Игорь Шевченко ©   (06.09.04 18:23) [31]

>Кстати, в приснопамятной программе МАРС такой подход >использовался, с ClientDataSet для работы с гридом, я бы не >сказал, что это сильно усложнило работу.
Да вроде бы не сильно. Правда я не помню как там с такой ситуацией:
- в базе коллекция объектов
- она отобразилась на коллекцию
- коллекция на датасет
- в датасете пользователь удалил запись потом вставил другую
когда идет обмен с базой?
если в момент обратного отображения клиентдатасета на коллекцию то нужно еще смотреть историю удалений, если параллельно с удалением из датасета - то часто дергается соединение с базой что не совсем то чего хочется достичь.


 
Игорь Шевченко ©   (2004-09-06 18:37) [33]

Sergey_Masloff   (06.09.04 18:34) [32]


> - в базе коллекция объектов
> - она отобразилась на коллекцию
> - коллекция на датасет
> - в датасете пользователь удалил запись потом вставил другую
> когда идет обмен с базой?


В момент сохранения всего объекта со всеми коллекциями в базе данных.


 
TohaNik ©   (2004-09-06 18:40) [34]

>Sergey_Masloff  (06.09.04 17:51) [16]

Вобщем, то ли руки мне еще править и править но пока полного консенсуса с чисто объектным подходом не получилось у меня.

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

это да, но как быть в случаях когда нужно работать с несколькими источниками данных, когда основная БД на Firebird, а данные в неё заливаются из dbf, текстовых файлов, и в этой заливке много бизнес логики. Тут одними SP не обойдешься

ИМХО здесь другое - подготовка данных чтобы были съедобны Firebird

...а бизнес логика на клиенте??...опять же ИМХО если проэкт достаточно большей, то в определенный момент с большой долей вероятности возникнет ситуация когда станет непонятным каким образом могли появиться некоторые нежелательные(неожидаемые) данные в базе и найти причину будет значительно тяжелей при признаваемой большинством громоздкости кода чем при вынесении этой бизнес логики на сервер


 
Sergey_Masloff   (2004-09-06 18:55) [35]

Игорь Шевченко ©   (06.09.04 18:37) [33]

У меня возникали проблемы когда объект может быть элементом нескольких коллекций одновременно. Когда возникают (в силу предметной области или кривых рук) отношения объектов не как деревьев а как графов.
 Ну (из теперешней области)
 Есть полис (объект).
 В нем есть коллекция участников и их ролей
 Полис - Роль (объект) <- Субъект (физ или юр. - объект)
       \ Роль (объект) <- Субъект (физ или юр. - объект)
       ...............................................  

 Кроме этого есть коллекция застрахованных объектов
 Полис - Объект <- Это тоже может быть субъект
       \ Объект <- а у этого объекта есть владелец - и он тоже  субъект.

Вобщем идея понятна - один и тот же объект (допустим физ. лицо) входит в несколько коллекций и из нескольких коллекций может быть к нему обращение с целью модификации. То есть возникает дилемма - хранить несколько таких объектов - проблеме синхронизации так как в разных могут оказаться разные данные. И запишется в базу - только один из вариантов (который будет сохраняться последним). Вариант второй - то что у Фауоера называется LazyLoad с пулом объектов. Я это и сам придумал до (ну ладно не до а независимо) от Фаулера только так красиво не смог название придумать. Но реализация не такая простая всего этого дела :(


 
GRAND25 ©   (2004-09-06 19:01) [36]

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

"... до основанья. А зачем?"


 
iZEN ©   (2004-09-06 19:12) [37]

2-й подход более объектно-ориентирован и более соответствует предметной области (моделирует реальные отношения).
Без сомнения он правильнее первого подхода, но он труден в реализации.


 
iZEN ©   (2004-09-06 19:24) [38]

/**by ©   (06.09.04 18:18) [28]
мечта такая у меня есть и сейчас, заманчиво реализовать Model View Controler и прочее. Но из реалий я вижу что очень много нужно писать, намного больше чем при модели через датасет, и это сдерживает.
*/
Совсем немного. Просто нужно взять/понять суть паттерна MVC и стараться не использовать "левого" толка.

Кстати, для работы с БД по парадигме MVC необходимо придумать политику обновления Вида, так как Модель, Вид и Контроллёр будут находиться на разных компьютерах и соединяться по относительно медленным каналам. Такая политика есть и описывается специальным(и) паттерном(ами) проектирования.


 
TohaNik ©   (2004-09-06 20:02) [39]

iZEN ©  (06.09.04 19:24) [38]

Ну а разве разработка модели это совсем немного...?

Наверное всетаки спор из-за того что предполагается исп-е ASP.NET
где где идеология "несколько" другая.

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


 
GRAND25 ©   (2004-09-06 20:11) [40]

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



Страницы: 1 2 вся ветка

Текущий архив: 2004.09.26;
Скачать: CL | DM;

Наверх




Память: 0.6 MB
Время: 0.065 c
1-1094844671
Viking
2004-09-10 23:31
2004.09.26
Assembler


3-1093518855
Marat
2004-08-26 15:14
2004.09.26
Максимальное количество столбцов


3-1094007540
HMT
2004-09-01 06:59
2004.09.26
Обновление содержимого blob.


1-1094835977
Rimas
2004-09-10 21:06
2004.09.26
Свойства панели задач


14-1094229906
VictorT
2004-09-03 20:45
2004.09.26
Уехать... оборвать все связи... сменить телефон, аську, мыло...