Comments 37
С вашей статьей согласен, спасибо.
Сам раньше подумывал о неком «db specific ORM», где можно было бы создавать слой работы с данными посредством хранимых процедур, представлений и прочих специфичных для той или иной СУБД конструкций (воспользоваться преимуществами каждой из них), а затем этот слой (точнее объектную надстройку над ним) использовать в объектной модели, в бизнесс логики. И (как было замечено) когда мы сохраняем данные о клиенте в БД — это совершенно не значит, что все они будут вставлены в одну плоскую таблицу Clients, но сам бизнесс слой об этом ничего не знает, и логику хранения можно изменять как угодно без его ведома.
Но хочу добавить, что плюс бизнес логики на стороне приложении (а не в БД) это возможность более легкого и простого масштабирования (распараллеливания). И думаю многие разработчики и команды сознательно идут на шаг полного игнорирования всех фич выбранной СУБД, и забивают ее каким-либо ORM'ом. Да, можно потерять в скорости, но никто не мешает поставить еще одну (две, три ...) машины рядом в помощь. Проще и быстрее.
Как и было сказано в этой статье, все зависит от конкретного приложения (и только от него) и условий его разработки.
Сам раньше подумывал о неком «db specific ORM», где можно было бы создавать слой работы с данными посредством хранимых процедур, представлений и прочих специфичных для той или иной СУБД конструкций (воспользоваться преимуществами каждой из них), а затем этот слой (точнее объектную надстройку над ним) использовать в объектной модели, в бизнесс логики. И (как было замечено) когда мы сохраняем данные о клиенте в БД — это совершенно не значит, что все они будут вставлены в одну плоскую таблицу Clients, но сам бизнесс слой об этом ничего не знает, и логику хранения можно изменять как угодно без его ведома.
Но хочу добавить, что плюс бизнес логики на стороне приложении (а не в БД) это возможность более легкого и простого масштабирования (распараллеливания). И думаю многие разработчики и команды сознательно идут на шаг полного игнорирования всех фич выбранной СУБД, и забивают ее каким-либо ORM'ом. Да, можно потерять в скорости, но никто не мешает поставить еще одну (две, три ...) машины рядом в помощь. Проще и быстрее.
Как и было сказано в этой статье, все зависит от конкретного приложения (и только от него) и условий его разработки.
Все очень сильно зависит от типа приложений, которые вы разрабатываете. Если это «справочники» с набором CRUD операций, то лепить объектный слой над ними большого смысла нет. А если приложение автоматизирует деятельность в какой-то предметной области, то без доменной модели и слоев абстракций вы очень скоро придете к несопровождаемому коду.
Раздел «Пошатнем мир идеалиста» вызвал у меня боль чуть ниже спины. API в виде хранимой процедуры и обоснование дублирования логики избавлением от лишних операций — вы в каком веке живете? Для того и развивается железо, чтобы прикладные программисты меньше думали о таких вещах и эффективнее решали бизнес-задачи, писали простой, легко сопровождаемый код.
Раздел «Пошатнем мир идеалиста» вызвал у меня боль чуть ниже спины. API в виде хранимой процедуры и обоснование дублирования логики избавлением от лишних операций — вы в каком веке живете? Для того и развивается железо, чтобы прикладные программисты меньше думали о таких вещах и эффективнее решали бизнес-задачи, писали простой, легко сопровождаемый код.
Вы что-то напутали, я нигде не обосновывал дублировние логики.
В разделе «Пошатнем мир идеалиста» я ставлю под вопрос необходимость объектно ориентированной модели в случае, когда нет необходимости в интерфейсе пользователя. Если Вы прочитали не так, попробуйте перечитать.
Так и прочитал. Но в приведенном вами примере было сказано, что интерфейс пользователя уже был. Следовательно, должен был быть слой логики. Т.е. приложение уже имело информацию об объектах. Для реализации логики проводок в базе вы должны были неизбежно продублировать ее там. Теперь, при изменении упомянутой вами логики конвертации, придется вносить правки в двух местах, логически не связанных.
Да и какое-то у вас противоречие, есть желание " эффективнее решать бизнес-задачи, писать простой, легко сопровождаемый код", и в то же время не хотим задумываться о «избавлении от лишних операций». Не находите это странным?
Нет, не нахожу. Еще раз: за избавление от некоторого количества операций ввода-вывода вы платите размытием логики между слоями, потерей механизмов абстракции в коде, отсутствием возможности использования современных инструментов и технологий разработки.
продублирую: «за избавление от некоторого количества операций ввода-вывода вы платите размытием логики между слоями» — это доведение до абсурда, тогда как «размытие локиги» — это только в головах разработчиков, а плата в виде «опираций ввода/вывода информации из базы» вполне ощутима.
Что же касается «отсутствием возможности использования современных инструментов и технологий разработки» — тут вы не правы. Если Вы внимательно читали, и понимаете под этим объектно ориентированную методологию, то я как раз написал в каких случая оно не нужно, и наоборо выгодно уступает языку SQL.
Ну и да, лишнии слои абстраций нужно не вводить всегда и везде, а использовать их только тогда когда они нужны. Для групповых операций SQL лучше работает на реляционных данных, чем на объектной абстракции.
Что же касается «отсутствием возможности использования современных инструментов и технологий разработки» — тут вы не правы. Если Вы внимательно читали, и понимаете под этим объектно ориентированную методологию, то я как раз написал в каких случая оно не нужно, и наоборо выгодно уступает языку SQL.
Ну и да, лишнии слои абстраций нужно не вводить всегда и везде, а использовать их только тогда когда они нужны. Для групповых операций SQL лучше работает на реляционных данных, чем на объектной абстракции.
Можно еще уточнить, что это не просто «избавление от некоторого количества операций ввода-вывода», это еще замена в определенных случаях удобного языка SQL на работу с объектами. Например, чтобы заменить update по таблице с определенными условиями, нужно вводить цикл с условиями. Мне совершенно не кажется, что применение менее удобного здесь механизма объектного языка («современных инструментов и технологий разработки»), лучше чем применение SQL для того, для чего он предназначен.
Да и потом, как Вы представляете себе «операции ввода» в описанном выше случае? заменить один update множеством update по каждому объекту под внешней транзакцией? Причем по одному полю, как вы это сделаете: на каждое поле введете хранимую процедуру, в одной хранимой процедуре будите проверять какое поле поданно для изменения, а какие оставить как есть, или вообще вынесите SQL из хранимой процедуры в объектный язык? И это того стоит? Ради чего?
Лично мне сложно ориентироваться в БД где больше сотни хранимок и несколько десятков функций.
Часто происходит дублирование логики, что приводит к сложностям при внесении изменений.
Может быть автор подскажет как он решает данные проблемы.
Часто происходит дублирование логики, что приводит к сложностям при внесении изменений.
Может быть автор подскажет как он решает данные проблемы.
С другой стороны, возможна и обратная ситуация: одну и ту же БД могут использовать несколько разных приложений, на разных языках (например, складской учет + веб-морда), и легко может возникнуть дублирование кода.
А код с более чем сотней классов вас при этом не смущает? Я согласен, что ООП позволяет лучше структурировать код. Ну скажем в нашем приложении более 2000 sql процедур, разбираться во всех их обычно никому не нужно. Как правило на отдельную задачу требуется набор не более, чем 5-10 sql-процедур, а это совсем не много, если еще как и все прочие нормально именовать и не забывать комментировать.
Мне кажется сосредоточить всю бизнес-логику в одном слое в принципе невозможно. Всё-равно она постепенно размазывается. Простой пример, имеем требование (вполне себе бизнес-требование): «поле Email контакта должно быть не пустым, уникальным и содержать валидный email-адрес».
Первым делом в базе данных добавляем на поле constraint not null, уникальный индекс, check constraint (validation rule) с проверкой валидности email. Вся логика в базе данных, хорошо. Но у гас есть веб-формочка, пользователям явно не понравится ждать после сабмита только для того, чтобы выяснить, что они забыли заполнить Email. Дублируем требование, добавляем проверку на не пустоту и валидность на JavaScript. Требование на уникальность на этом уровне реализовать затруднительно. Аналогичные проверки нужны на сервере приложения, мы же не можем доверять проверкам на клиенте. Итого, одно бизнес-правило размазалось по всем слоям с разным уровнем детализации.
Первым делом в базе данных добавляем на поле constraint not null, уникальный индекс, check constraint (validation rule) с проверкой валидности email. Вся логика в базе данных, хорошо. Но у гас есть веб-формочка, пользователям явно не понравится ждать после сабмита только для того, чтобы выяснить, что они забыли заполнить Email. Дублируем требование, добавляем проверку на не пустоту и валидность на JavaScript. Требование на уникальность на этом уровне реализовать затруднительно. Аналогичные проверки нужны на сервере приложения, мы же не можем доверять проверкам на клиенте. Итого, одно бизнес-правило размазалось по всем слоям с разным уровнем детализации.
1. Может, я что-то упустил, но как вы в итоге получаете конечную объектную модель для ее отображения, если БД, насколько я помню, в большинстве своем умеют отдавать только одно- и двухмерные данные? Скажем, та же сводная страница покупателя, на которой нужны ФИО, адрес, список его заказов с подробным перечнем товаров, пересчетами валют и скидками, использованные купоны… Фантазия заказчика, к сожалению, безгранична. Вы их как-то упаковываете в таблицы или достаете кучей разных запросов, а потом сшиваете в клиенте/middleware? Не было ситуаций, когда для «сшивки» данных все равно требовались какие-то бизнес-правила? Хотя ими тоже можно напрячь базу данных… Но тогда не возникнет ли противоречие вашей стратегии оптимизации (не использовать второй слой для того, что умеет сама БД), ибо базе придется либо формировать сложные результирующие данные, либо кешировать промежуточные запросы (если вы получаете данные несколькими заходами-процедурами), либо таки дублировать их.
2. ИМХО, бизнес-логику выносят в отдельный слой (tier, если угодно) с идеей упрощения архитектуры — «БД умеет только CRUD и больше ничего, клиент умеет только получать и дооформлять данные (например, через XSLT — особо тяжелых вычислений на клиенте быть не должно), а также формировать запросы, а центральный сервер умеет только парсить запросы клиента, дергать БД, что-то вычислять и формировать конечный отклик». Те же сортировки-группировки-курсоры можно считать частью бизнес-логики, лежащей на центральном сервере, а БД воспринимать исключительно как интерпретатор сложных запросов, а не как самостоятельный «мозговой центр» (по сути, между «дай мне всю таблицу» и «по хитрожопому отJOINь десять таблиц и прогруппируй по двадцати столбцам в случайном порядке» никакой разницы — что БД сказали делать, то она и сделает без особой инициативы).
2. ИМХО, бизнес-логику выносят в отдельный слой (tier, если угодно) с идеей упрощения архитектуры — «БД умеет только CRUD и больше ничего, клиент умеет только получать и дооформлять данные (например, через XSLT — особо тяжелых вычислений на клиенте быть не должно), а также формировать запросы, а центральный сервер умеет только парсить запросы клиента, дергать БД, что-то вычислять и формировать конечный отклик». Те же сортировки-группировки-курсоры можно считать частью бизнес-логики, лежащей на центральном сервере, а БД воспринимать исключительно как интерпретатор сложных запросов, а не как самостоятельный «мозговой центр» (по сути, между «дай мне всю таблицу» и «по хитрожопому отJOINь десять таблиц и прогруппируй по двадцати столбцам в случайном порядке» никакой разницы — что БД сказали делать, то она и сделает без особой инициативы).
1. Конечно должен использовать второй вариант: «формировать сложные результирующие данные». Но в это определенно нет ни каких бизнес-правил, т.е. такого нет «для «сшивки» данных все равно требовались какие-то бизнес-правила». Единственно, конечно group и order можно считать бизнес-правилами, но им там и место.
2. Ну, вот эта идея и не правильна в корне, если используется как истина в последней инстанции. В статье как раз указаны случаи, когда это крайне излишно и не удобно для реализации. Выполнение каких то принципов лишь для того, чтобы выполнить или как мне выше написали «за избавление от некоторого количества операций ввода-вывода вы платите размытием логики между слоями» — это доведение до абсурда, тогда как «размытие локиги» — это только в головах разработчиков, а плата в виде «опираций ввода/вывода информации из базы» вполне ощутима.
2. Ну, вот эта идея и не правильна в корне, если используется как истина в последней инстанции. В статье как раз указаны случаи, когда это крайне излишно и не удобно для реализации. Выполнение каких то принципов лишь для того, чтобы выполнить или как мне выше написали «за избавление от некоторого количества операций ввода-вывода вы платите размытием логики между слоями» — это доведение до абсурда, тогда как «размытие локиги» — это только в головах разработчиков, а плата в виде «опираций ввода/вывода информации из базы» вполне ощутима.
Вы так и не ответили на вопрос, как вы тянете результаты работы бизнес-логики из базы данных.
Ситуация: есть некий интернет-магазин. В нем есть товары. У товаров, как ни странно, есть цены.
И все бы хорошо, и иногда действительно нужно запихнуть бизнес-логику в базу данных — например, без пересчетов валют и скидок не будет работать сортировка товаров по цене. Однако как из описанной мною выше ситуации из базы данных вытянуть информацию о заказе, которая должна включать в себя все товары, их обычные цены, цены со скидками (мы любим рисовать зачеркнутые цены), выбранные параметры товаров (их может быть сколько угодно — хоть ноль, хоть один, хоть 30), выбранные способы доставки/оплаты, все промежуточные точки расчета групповых скидок, налогов и итоговую сумму? Результат запроса-то у нас двухмерный. Будете городить стремные конструкции из диких JOIN и UNION, чтобы все уместить в одно отношение, или же разобьете запрос на несколько маленьких, и они будут дублировать части друг друга (например, отдельно список товаров и их параметры, отдельно сумма этого же списка + скидки/налоги + итог)?
Ситуация: есть некий интернет-магазин. В нем есть товары. У товаров, как ни странно, есть цены.
- Во-первых, эти цены бывают в разных валютах — нужно знать текущие курсы и уметь их пересчитывать (как для отображения в каталоге, так и для расчета суммы заказа).
- Во-вторых, существуют скидки на определенные группы товаров — их также нужно отображать в каталоге и учитывать при суммировании. Скидки, кстати, бывают не только "-20%", но и «купи две — третья бесплатно». Уже хорошо как для алгоритма, так и для администратора интернет-магазина (он не полный идиот и не будет переписывать каждый раз сложные процедуры — он настроит скидки в админке, а система сгенерирует SQL для процедуры сама).
- В-третьих, бывают хитрые условия доставки и оплаты a-la «доставка от 2500 рублей бесплатна, но при доставке за МКАД оплачивается каждый километр; также учитывается вес заказа, подъем на этаж и фаза луны».
- В-четвертых, бывает, что налоги рассчитываются из разных «точек» — от суммы цен товаров, от суммы цен товаров с учетом скидок, от суммы заказа с учетом предыдущих налогов...
- Самое прикольное (в моем списке) — в-пятых: товары могут иметь различные настраиваемые параметры, от которых также может зависеть их цена (цвет, комплектация etc). Весело, не так ли?
И все бы хорошо, и иногда действительно нужно запихнуть бизнес-логику в базу данных — например, без пересчетов валют и скидок не будет работать сортировка товаров по цене. Однако как из описанной мною выше ситуации из базы данных вытянуть информацию о заказе, которая должна включать в себя все товары, их обычные цены, цены со скидками (мы любим рисовать зачеркнутые цены), выбранные параметры товаров (их может быть сколько угодно — хоть ноль, хоть один, хоть 30), выбранные способы доставки/оплаты, все промежуточные точки расчета групповых скидок, налогов и итоговую сумму? Результат запроса-то у нас двухмерный. Будете городить стремные конструкции из диких JOIN и UNION, чтобы все уместить в одно отношение, или же разобьете запрос на несколько маленьких, и они будут дублировать части друг друга (например, отдельно список товаров и их параметры, отдельно сумма этого же списка + скидки/налоги + итог)?
Я Вам ответил «Конечно должен использовать второй вариант: «формировать сложные результирующие данные»». Т.е. да буду использовать JOIN и UNION. Но при вашем уточнении могу уточнить, все зависит как это мы будем отображать. В вашем примере, я сомниваюсь, что все параметры отображаются сразу. Как правило, пользователю вначале показывается список из сокращенных параметров но по всем товарам, а потом при выборе товара показывается более подробная информация по одному товару. Это позволит разгрузить пользователя от детальной информации при выборе, и дать детально когда выбран уже товар. Тогда это два select`а.
Я вам дам пример одного простенького select`a из моей игры, получение состояния персонажа (думаю подобные вопросы отпадут):
select att1.Value as Health, att2.Value as Energy, att3.Value as Cheerfulness,
att4.Value as Intelligence, att5.Value as Money,
att19.Value as TKomfort,
c.Name as CityName,
CONCAT(' (', c.TemperatureAir, ' °C)') as TemperatureAir,
a.CityID, c.X as CityX, c.Y as CityY, c.AllowPort as AgentCityIsPort,
a.ArrivalTime,
IF (a.CityIDDestination <> 0, c2.Name, '') as CityNameDestination,
IF(a.ArrivalTime > SYSDATE(),
TIME_TO_SEC(TIME(SUBTIME(a.ArrivalTime, SYSDATE()))), 0) as RemainingTime,
GetGameSec() as GameSec, GetGameDate() as GameDate,
a.OrganizationID as OrgID, a.ProfessionID as ProfID, p.Name as ProfName,
IF (a.ProfessionID IN (2, 4), g.Name, IF (a.ProfessionID IN (3, 5), o.Name,
IF (a.ProfessionID IN (6, 7), m.Name, '')) ) as OrgName,
a.AccessType, a.VoteForAgentID, a2.Name as VoteForAgentName,
IF (a.ProfessionID = 5, o.Tax, 0) as GuildTax,
IFNULL(pm.Mode, 0) as PlanMode, a.IsDead,
a.FightID, a.FightStep,
IF (exists (select * from Stock where AgentID = locAgentID and CityID = a.CityID), 1, 0) as IsStock,
IFNULL(t1.Level, 1) as HouseL, IFNULL(t2.Level, 1) as WorkshopL,
IFNULL(t3.Level, 1) as FarmL, IFNULL(t4.Level, 1) as ClinicL,
IFNULL(t5.Level, 1) as TrafficL, IFNULL(t6.Level, 1) as ArmoryL,
IFNULL(t7.Level, 1) as ForestL, IFNULL(t8.Level, 1) as RiverL,
IFNULL(t9.Level, 1) as FieldL, IFNULL(t10.Level, 1) as HillL,
ca.ImageName as CoatsOfArmsName, a.AgentType, a.Name as AgentName
from Agents as a
join Cities as c on c.ID = a.CityID
left join Cities as c2 on c2.ID = a.CityIDDestination
join Professions as p on p.ID = a.ProfessionID
left join GuildOfMerchants as g on g.ID = a.OrganizationID
left join OrderOfKnights as o on o.ID = a.OrganizationID
left join Manufactory as m on m.ID = a.OrganizationID
left join Agents as a2 on a2.ID = a.VoteForAgentID
join AgentAttribute as att1 on att1.AttributeID = 1 and att1.AgentID = locAgentID
join AgentAttribute as att2 on att2.AttributeID = 2 and att2.AgentID = locAgentID
join AgentAttribute as att3 on att3.AttributeID = 3 and att3.AgentID = locAgentID
join AgentAttribute as att4 on att4.AttributeID = 4 and att4.AgentID = locAgentID
join AgentAttribute as att5 on att5.AttributeID = 5 and att5.AgentID = locAgentID
join AgentAttribute as att19 on att19.AttributeID = 19 and att19.AgentID = locAgentID
left join PlansMode as pm on pm.AgentID = a.ID
left join coats_of_arms as ca on ca.ID = a.CoatsOfArmsID
left join AgentTerritory as t1 on t1.AgentID = a.ID and t1.CityID = a.CityID and t1.TerritoryID = 8
left join AgentTerritory as t2 on t2.AgentID = a.ID and t2.CityID = a.CityID and t2.TerritoryID = 6
left join AgentTerritory as t3 on t3.AgentID = a.ID and t3.CityID = a.CityID and t3.TerritoryID = 5
left join AgentTerritory as t4 on t4.AgentID = a.ID and t4.CityID = a.CityID and t4.TerritoryID = 7
left join AgentTerritory as t5 on t5.AgentID = a.ID and t5.CityID = a.CityID and t5.TerritoryID = 25
left join AgentTerritory as t6 on t6.AgentID = a.ID and t6.CityID = a.CityID and t6.TerritoryID = 9
left join AgentTerritory as t7 on t7.AgentID = a.ID and t7.CityID = a.CityID and t7.TerritoryID = 1
left join AgentTerritory as t8 on t8.AgentID = a.ID and t8.CityID = a.CityID and t8.TerritoryID = 4
left join AgentTerritory as t9 on t9.AgentID = a.ID and t9.CityID = a.CityID and t9.TerritoryID = 3
left join AgentTerritory as t10 on t10.AgentID = a.ID and t10.CityID = a.CityID and t10.TerritoryID = 2
where a.ID = locAgentID;
У Вас есть альтернатива этому select`у? (и заметим в скобках, в этом select`е нет ни грамма бизнес-логики)
Никто не говорил об альтернативах — я просто уточнял вашу идею (^_-) И, кстати, даже с точки зрения «база данных только для CRUD» оно не кажется из ряда вон выходящим (ИМХО, конечно). Хотя, на мой взгляд,
CONCAT(' (', c.TemperatureAir, ' °C)')
— ерунда, потому что отображение около числа надписи "°C" или «в градусах Цельсия» (и уж тем более заключение значения в скобки) — задача только представления и ничья больше. Даже бизнес-логика оперирует данными, такими, как «5» или «значение в градусах Цельсия» (последнее скорее как абстрактная идея, значение enum, отвечающего за шкалу, нежели как конкретное высказывание).ну придрались к мелочи :) Ваше замечание имеет смысл только тогда, когда тем-ра участвует в вычислениях (в данном случае на JavaScripte), в моем же случае там это не происходит. А лепить лешего ради какой-то умозрительной чистоты — я естественно не буду, т.к. это просто излишнее.
в этом же селекте есть ровно обратный пример: c.X as CityX, c.Y as CityY — координаты города. Они используются в вычислениях, чтобы отрисовать город на карте, и в тоже время координаты города отображаются игроку в формате (x-y). Если бы нужно было бы только второе, вы увидили бы еще один CONCAT. Поэтому все по необходимости. И это не бизнес-логика, просто все зависит какой объект нужно получить на стороне клиента. А объект создается из требований задачи.
Кстати, плата за «размытие логики» = оплата разработчикам лишних трудовых часов, необходимых для «вспоминания» архитектуры и всех нюансов, сделанных ради скорости работы всей системы. Вопросы, обозначенные в посте, обычно поднимаются на крупных проектах, с которыми работают весьма объемные команды с неплохой почасовой ставкой (не наши детсадовские 1000-2000$). Да, опыта и личных качеств им не занимать (иначе бы не платили), но все-таки это люди, и им нужно входить в контекст, в поток. Сравнима ли стоимость подобных оптимизаций с точки зрения оплаты труда (это я еще не считаю другие расходы) со стоимостью медленной работы конечной системы? Или вы всю жизнь занимались разработкой биржевых экономических систем и игровых движков, где скорость работы крайне критична?
«плата за «размытие логики» = оплата разработчикам лишних трудовых часов, необходимых для «вспоминания» архитектуры и всех нюансов, сделанных ради скорости работы всей системы.»
Я хочу подчеркнуть, что это делается как раз не ради скорости работы системы (хотя и это тоже), а для ускорения разработки и более простого сопровождения потом. А «вспоминания» архитектуры — происходит всегда не зависимо от того, какая эта логика. Это даже не «размытие логики» — это просто написание логики с использованием разных средств.
Более того, логику в базе данных и на объектном языке вполне могу делать разные разработчики.
Я хочу подчеркнуть, что это делается как раз не ради скорости работы системы (хотя и это тоже), а для ускорения разработки и более простого сопровождения потом. А «вспоминания» архитектуры — происходит всегда не зависимо от того, какая эта логика. Это даже не «размытие логики» — это просто написание логики с использованием разных средств.
Более того, логику в базе данных и на объектном языке вполне могу делать разные разработчики.
Ускорение разработки? Это вы про то, что разработчику приходится переключаться между языком высокого уровня и процедурами SQL, разнящимися от базы к базе? Или про то, что ценой этапа синхронизации модулей программы из разных сред (Java и Oracle DB разные же среды, не так ли?), который, опять же, стоит дороже синхронизации модулей из одной среды (проще отладить два куска Java, чем Java и интерпретатор запросов/процедур SQL-базы), можно распараллелить разработку (интересно, что мешает двум разработчикам писать на одном языке)?
Кстати, вы с таким подходом с миграциями и версионностью разрабатываемых систем работали? Миграция таблиц и данных в них — уже целое приключение, а хранимые процедуры и сложные вьюхи…
Кстати, вы с таким подходом с миграциями и версионностью разрабатываемых систем работали? Миграция таблиц и данных в них — уже целое приключение, а хранимые процедуры и сложные вьюхи…
Было бы очень страно, если бы одно приложение использовало бы разные базы данных. Поэтому «разнящимися от базы к базе» — это совсем мимо.
А «переключаться между языком высокого уровня и процедурами SQL» — это просто не серьезно. Обычно просто пишется слой на SQL, а потом на объектном языке, если второе вообще требуется. А без первого вы вообще не напишите ни одно приложение, поэтому так или иначе будите переключаться, что совсем кстати не сложно.
Ну и потом альтернативы то у вас нет :)
А «переключаться между языком высокого уровня и процедурами SQL» — это просто не серьезно. Обычно просто пишется слой на SQL, а потом на объектном языке, если второе вообще требуется. А без первого вы вообще не напишите ни одно приложение, поэтому так или иначе будите переключаться, что совсем кстати не сложно.
Ну и потом альтернативы то у вас нет :)
Не поддерживали вы студенческие недоделки, ой не поддерживали… Вы бы не только разные БД в одной системе увидели. Хотя я имел в виду «одну систему написать с использованием SQL Server, другую на Оракле, третью на MySQL, четвертую на SQLite, PostgreSQL...» — повторюсь, есть разные заказчики и разные требования, и иногда слова «тут неуместна SQL Server, и мне все равно, что вы пять лет назад купили лицензию, и поэтому должны ее отработать» могут стоить проекта тысяч на 500. Впрочем, против такого идеализма я ничего не имею.
Ну тут Вы правы, я привык к тому, что мы диктуем минимальные требования к установке системы (в том числе и в плане лицензий), а не нам заказчик.
Просто это аналогично тому, что мы написали ПО на C#, а заказчик захотел чтобы она была на Java :) Перевести можно, но почему то считается, что PL-SQL должен почему то легко (или автоматически?) переводится на T-SQL
Хотя, я конечно не совсем точен. Даже в моей игрушке две базы — MySQL и SQL Server Express, но у них разные задачи. SQL Server Express используется для авторизации пользователя, т.к. ASP.NET несколько автоматизирует этот процесс, ну и потом оказалось удобно держать аккаунты отдельно от логики игры. Но эти базы практически не пересекаются.
Последние не касается этой темы ни как.
Наверно подводя некий итог, я хочу сказать, точнее еще раз сделать на этом акцент, что существует разная бизнес-логика. Есть бизнес-логика вполне себе замкнутая в себе, которую удобно реализовывать с помощью SQL. И есть другая бизнес-логика, связанная с управлением интерфейса пользователя. Эта логика порой сильно сложнее в плане реализации, и тут без объектной методологии не обойтись.
Простое управление интерфейсом, как в некоторых веб-приложениях, может обойтись и без объектной методологии. Если попытаться найти критерий, когда эта сложность возникает, то получается следующие. Минимальное условие — это отсутствие перевыбора всей порции данных (как это имеет место при генерации новых HTML-страниц в ответ на реакцию пользователя). Вот такой пример, открывается уже готовый платеж, требуется при изменении суммы платежа, пересчитать тут же тариф, если не хватает денег тут же пересчитать конвертацию из доступных средств. Это один сценарий. Второй пользователь меняет тариф, снова же автоматически происходит конвертация. Третий сценарий, меняется срочность платежа, это тоже меняет расчет тарифа. Так вот бизнес-логика собственно расчета тарифа и конвертации должна быть отделенна и реализованна SQL -ом, а правила вызова этого SQL в зависимости от сценариев работы пользователем должны быть реализованны в объектной методологии. Причем важно тут то, что действительно есть сценарии работы пользователя, которые различаются, но частично дублируются. Пересчет тарифа в зависимости от сменны различных параметров. Если таких сценариев нет — то и необходимости в объектной методологии нет для обслуживания такого интерфейса.
Простое управление интерфейсом, как в некоторых веб-приложениях, может обойтись и без объектной методологии. Если попытаться найти критерий, когда эта сложность возникает, то получается следующие. Минимальное условие — это отсутствие перевыбора всей порции данных (как это имеет место при генерации новых HTML-страниц в ответ на реакцию пользователя). Вот такой пример, открывается уже готовый платеж, требуется при изменении суммы платежа, пересчитать тут же тариф, если не хватает денег тут же пересчитать конвертацию из доступных средств. Это один сценарий. Второй пользователь меняет тариф, снова же автоматически происходит конвертация. Третий сценарий, меняется срочность платежа, это тоже меняет расчет тарифа. Так вот бизнес-логика собственно расчета тарифа и конвертации должна быть отделенна и реализованна SQL -ом, а правила вызова этого SQL в зависимости от сценариев работы пользователем должны быть реализованны в объектной методологии. Причем важно тут то, что действительно есть сценарии работы пользователя, которые различаются, но частично дублируются. Пересчет тарифа в зависимости от сменны различных параметров. Если таких сценариев нет — то и необходимости в объектной методологии нет для обслуживания такого интерфейса.
Вот и получается, что для веб приложений практически вся бизнес-логика находится в базе данных
Для вашего приложения. Но им, к счастью, мир веб-приложений не исчерпывается.
А задача сервера сводится к формированию HTML страниц для клиента.
У вас просто сервер простой, вот и все.
Sign up to leave a comment.
Где наша бизнес-логика для идеалиста?