Зачем нам нужны сущностные объекты? [закрыто]


140

Мне действительно нужно увидеть честные и вдумчивые дискуссии о достоинствах принятой в настоящее время парадигмы проектирования корпоративных приложений .

Я не уверен, что объекты сущностей должны существовать.

Под объектами сущностей я подразумеваю типичные вещи, которые мы обычно создаем для наших приложений, такие как «Человек», «Учетная запись», «Заказ» и т. Д.

Моя текущая философия дизайна такова:

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

(Примечание: я также создавал корпоративные приложения с Java EE, люди, использующие Java, пожалуйста, замените эквивалент в моих примерах .NET)

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

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

Я использовал OR Mappers. Я написал несколько. Я использовал стек Java EE, CSLA и несколько других эквивалентов. Я не только использовал их, но и активно разрабатывал и поддерживал эти приложения в производственных средах.

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

Рассмотрим этот простой пример: вы получаете звонок в службу поддержки о том, что определенная страница в вашем приложении работает некорректно, возможно, одно из полей не сохраняется, как должно быть. В моей модели разработчик, которому поручено найти проблему, открывает ровно 3 файла . ASPX, ASPX.CS и файл SQL с хранимой процедурой. Проблема, которая может быть отсутствующим параметром при вызове хранимой процедуры, требует нескольких минут. Но с любой моделью сущности вы неизменно запускаете отладчик, начинаете пошагово выполнять код, и в итоге вы можете открыть 15-20 файлов в Visual Studio. К тому времени, когда вы перейдете в конец стопки, вы забудете, с чего начали. Мы можем держать в голове только определенное количество вещей одновременно. Программное обеспечение невероятно сложное без добавления ненужных слоев.

Сложность разработки и устранение неполадок - это лишь одна сторона моей проблемы.

Теперь поговорим о масштабируемости.

Понимают ли разработчики, что каждый раз, когда они пишут или модифицируют любой код, который взаимодействует с базой данных, им необходимо проводить тщательный анализ точного воздействия на базу данных? И не только копия для разработки, я имею в виду имитацию производства, поэтому вы можете видеть, что дополнительный столбец, который вам теперь нужен для вашего объекта, только что сделал недействительным текущий план запроса, и отчет, который запускался за 1 секунду, теперь займет 2 минуты, просто потому что вы добавили один столбец в список выбора? И оказывается, что индекс, который вам теперь нужен, настолько велик, что администратору базы данных придется изменить физическую структуру ваших файлов?

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

Я не фанатик. Я могу быть уверен, что ошибаюсь, и, возможно, ошибаюсь, поскольку существует такой сильный толчок к Linq to Sql, ADO.NET EF, Hibernate, Java EE и т. Д. Пожалуйста, подумайте над своими ответами, если мне что-то не хватает, я действительно хочу знать, что это такое, и почему я должен изменить свое мышление.

[Редактировать]

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

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

Одна вещь, которую я должен поставить здесь вверху в ответ на несколько похожих ответов: ортогональность и разделение проблем часто упоминаются как причины для перехода на entity / ORM. Для меня хранимые процедуры - лучший пример разделения задач, о котором я могу думать. Если вы запрещаете любой другой доступ к базе данных, кроме как через хранимые процедуры, вы теоретически можете перепроектировать всю свою модель данных и не нарушать какой-либо код, пока вы поддерживаете входные и выходные данные хранимых процедур. Они являются прекрасным примером программирования по контракту (при условии, что вы избегаете «select *» и документируете наборы результатов).

Спросите кого-нибудь, кто долгое время работал в отрасли и работал с долгоживущими приложениями: сколько уровней приложений и пользовательского интерфейса появилось и исчезло, пока существовала база данных? Насколько сложно настроить и реорганизовать базу данных, когда существует 4 или 5 различных уровней персистентности, генерирующих SQL для доступа к данным? Вы ничего не можете изменить! ORM или любой код, генерирующий SQL, блокируют вашу базу данных на камне .


Читая ваш вопрос, мы очень похожи, и я уже много лет задавался вопросом об одном и том же (с тех пор, как услышал о сторонних фреймворках сущностей, а теперь и о Microsoft)
pearcewg

1
Вы говорите, что бизнес-логика - это вспомогательные объекты или хранимые процессы? Я спрашиваю, поскольку многие люди, кажется, думают, что вы говорите позже ... но я думаю, что вы говорите, что у вас все еще есть бизнес-логика в закодированных объектах, вы просто получаете данные прямо из базы данных и используете эти данные , а не ORM или сопоставление со специализированными объектами для хранения данных. Я склонен думать так же, но в настоящее время я также оцениваю EF4, чтобы понять, стоит ли оно того.
alchemical

«потребители-новаторы часто оказываются в ловушке». - кто-то с опытом
Угур Гюмюшхан

Я унаследовал систему с более чем 2500 SPROC, в которой приложение рассматривается просто как средство активации SPROC и осмысления их вывода. Каждому считываемому и записываемому данным соответствует собственный SPROC. Центральных точек контроля нет. Он ужасен и податлив, как гранит. Я рассматриваю возможность оптимизации баз данных. 2500 SPROCS поставили меня на место. По сравнению с системой с хорошо организованным уровнем домена и повторно используемым кодом DAL она выглядит непродуманной и представляет собой кошмар для службы поддержки. Простые задачи занимают часы и разрушают душу. SPROC должны использоваться для высоких нагрузок или специальных методов IMO
trucker_jim

О вашем «отладочном» примере: с модульными тестами вы гораздо быстрее узнаете, где что-то идет не так.
MarioDS

Ответы:


59

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

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


Кристофер, похоже, вы воскресили этот вопрос, связавшись с ним из другого вопроса. Мне интересно, что вы подразумеваете под «богатыми взаимодействиями» и как было бы непрактично реализовать их без объектов?
Eric Z Beard,

4
Все, что можно делать с объектами, можно делать и без объектов. Я считаю, что объектно-ориентированный дизайн обычно намного проще, чем не-объектно-ориентированные методы для выполнения чего-либо «сложного», но я понимаю, что это работает не для всех.
Кристофер Джонсон,

Я согласен - ответ «когда использовать объекты» зависит от того, могут ли свойства объектов требовать действий или изменения бизнес-логики. Например, экземпляры User или Person могут иметь Password и LoginName -> действия вашего кода изменяются в соответствии с их значениями. Напротив, если бы у вас был Продукт, вам нужно было бы отображать (не более того, никаких других действий), чем получить DataSet из db и просто создать графический интерфейс.
Йордан Георгиев

5
Баланс есть. Избегайте религии и выбирайте то, что работает.
Джефф Дэвис

27

Теория утверждает, что путь вперед - это высокосвязные, слабосвязанные реализации.

Итак, я полагаю, вы ставите под сомнение этот подход, а именно разделение проблем.

Должен ли мой файл aspx.cs взаимодействовать с базой данных, вызывать sproc и понимать IDataReader?

В командной среде, особенно когда у вас меньше технических специалистов, работающих с aspx-частью приложения, мне не нужно, чтобы эти люди могли «прикоснуться» к этому материалу.

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

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

Кроме того, ваш подход, кажется, защищает бизнес-логику вашего приложения, чтобы находиться в вашей базе данных? Мне это кажется неправильным, SQL действительно хорош для запроса данных, а не, imho, для выражения бизнес-логики.

Интересная мысль, хотя она кажется в одном шаге от SQL в aspx, который из моих старых плохих неструктурированных дней asp наполняет меня ужасом.


Я согласен с тем, что наличие большого количества динамического SQL, разбросанного по всему коду, - зло. Вы должны сделать вызовы Db четкими и отчетливыми. Обертывание вызовов sproc в статических вспомогательных методах позволяет добиться своего рода разделения, не продвигаясь полностью по маршруту ORM.
Eric Z Beard,

1
Хотя я никогда не работал в среде asp, я уверен, что некоторые из менее технических людей взорвут ваши носки с помощью некоторого кода javascript на стороне клиента, что приведет к прекрасному пользовательскому интерфейсу независимо от какого-либо дрянного интерфейса к технической спине. -конец.
Crowne

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

2
«Мне кажется, что это неправильно, SQL действительно хорош для запросов к данным, а не, imho, для выражения бизнес-логики». - Если вы, скажем, не используете PL / SQL, который добавляет богатый язык программирования поверх (и тесно интегрирован с) SQL, и ваш код хранится в базе данных. Повышает производительность, избегая сетевых обходов. И инкапсулирует вашу бизнес-логику независимо от того, какой клиент подключается к базе данных.
ObiWanKenobi

25

Одна из причин - отделение модели предметной области от модели базы данных.

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


9
Должен сказать, что я действительно не согласен, по крайней мере, в отношении корпоративных приложений. Данные - это приложение.
Eric Z Beard,

3
зачем вам две разные модели одних и тех же данных?
Сеун Осева,

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

1
Думаю, это хорошая идея, реализованная плохо.
Джефф Дэвис,

21

Для меня это сводится к тому, что я не хочу, чтобы мое приложение заботилось о том, как хранятся данные. Я, вероятно, получу пощечину за то, что говорю это ... но ваше приложение - это не ваши данные, данные - это артефакт приложения. Я хочу, чтобы мое приложение мыслило категориями клиентов, заказов и элементов, а не такими технологиями, как DataSets, DataTables и DataRows ... потому что кто знает, как долго они будут работать.

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

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

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


3
«ваше приложение - это не ваши данные, данные - это артефакт приложения». - Приложение бесполезно без данных. Данные имеют большую ценность без приложения. Приложения приходят и уходят (их переписывают) все время, данные в любом нетривиальном приложении всегда сохраняются. И модель данных остается удивительно стабильной с течением времени.
ObiWanKenobi

16

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

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

К каждой строчке кода следует относиться с подозрением.


2
Конечно, это действительно хорошо работает, когда у вас есть масса персонала и ресурсов, но я думаю, что если вы команда из одного человека, подумайте, что «новые» методы могут очень помочь ...
Карл Хёрберг

10

Я хотел бы ответить примером, аналогичным тому, который вы предложили.

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

Что (на мой взгляд) сущности привносят в проект:

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

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

Разделение задач: в большом продукте вы можете назначить базу данных администратору базы данных, и он сможет чертовски оптимизировать ее. Назначьте модель бизнес-эксперту, обладающему необходимыми знаниями для ее разработки. Назначьте отдельные формы разработчикам, более опытным в веб-формах и т. Д.

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

Ура.


2
Хранимые процедуры, вероятно, являются лучшим примером ортогональности и разделения проблем. При правильном использовании они полностью инкапсулируют базу данных.
Eric Z Beard,

1
@Eric Z Beard: Да, но как вы можете писать модульные тесты для хранимых процедур, изолируя только логику внутри хранимой процедуры? Хранимые процедуры тесно связаны с базой данных, и большинству из нас, использующих ORM, это не нравится. Чтобы написать модульный тест для хранимой процедуры, вам нужно будет полагаться на определенные данные, которые будут в базе данных. и вы не можете повторно запускать этот тест снова и снова без этой зависимости данных. Этот тест, который вы напишете, больше не будет модульным тестом, а вместо этого будет тестом интеграции.
7wp,

8

Я думаю, что вы можете «откусить больше, чем можете прожевать» по этой теме. Тед Ньюард не был легкомысленным, когда назвал это « Вьетнамом компьютерных наук ».

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

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

Если вы хотите продолжить чтение с обеих сторон, посмотрите статьи в блоге Теда, Айенде Рахейн, Джимми Нильсона, Скотта Беллвэра, Alt.Net, Стивена Форте, Эрика Эванса и т. Д.


1
Вы правы, большинство людей не изменят своего мнения. Я понимаю, что в центре внимания Stack Overflow должны быть объективные вопросы, но субъективные вопросы намного веселее! Лично я многому научился из этого обсуждения.
Eric Z Beard,

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

Вау. +1 за ссылку на статью "Vietnam of Computer Science", в которой есть отличное введение в тему ORM и не ORM.
lambacck

7

@ Дэн, извини, я не это ищу. Я знаю теорию. Ваше утверждение «это очень плохая идея» не подкреплено реальным примером. Мы пытаемся разрабатывать программное обеспечение за меньшее время, с меньшим количеством людей, с меньшим количеством ошибок, и нам нужна возможность легко вносить изменения. Ваша многослойная модель, по моему опыту, отрицательна во всех вышеперечисленных категориях. Особенно в том, что касается создания модели данных в последнюю очередь. Физическая модель данных должна стать важным фактором с первого дня.


вау, кто-то другой, кто думает об этом так же, как я ... мои приложения почти всегда предназначены для манипулирования данными, это то, что они на самом деле делают.
alchemical

Это было бы лучше в качестве комментария теперь, когда эти функции доступны
Casebash

1
Простите меня за педантизм, но поскольку это популярный вопрос, а ошибка, которую вы сделали, является частой, я подумал, что должен указать на нее. «Меньше времени» - правильно, но «меньше людей» и «меньше ошибок» должно означать «меньше людей» и «меньше ошибок». Если у вас меньше муки, вы можете приготовить меньше печенья. (Кроме того, если вы используете слишком много муки, вы сделаете слишком много печенья - о чем редко забывают.) И снова мои извинения; просто пытаюсь быть полезным.
WCWedin

4

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


Это было бы лучше в качестве комментария
Casebash 09

4

Объекты Entity могут облегчить кеширование на уровне приложения. Удачи в кэшировании устройства чтения данных.


4

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

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

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

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

Это правда , что данные живут дольше , чем приложения, но считают эту цитату из Дэвида Laribee : Модели навсегда ... данные счастливый побочный эффект.

Еще несколько ссылок по этой теме:


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

4

Действительно интересный вопрос. Честно говоря, я не могу доказать, почему сущности хороши. Но могу поделиться своим мнением, почему они мне нравятся. Код вроде

void exportOrder(Order order, String fileName){...};

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

Реализация этого метода будет осуществляться на основе абстракции Order, а не на основе того, как именно он представлен в БД. Большинство таких операций, которые я реализовал, действительно не зависят от того, как хранятся эти данные. Я понимаю, что некоторые операции требуют связи со структурой БД для повышения производительности и масштабируемости, но по моему опыту их не так много. По моему опыту, очень часто достаточно знать, что Person имеет .getFirstName (), возвращающий String, и .getAddress (), возвращающий адрес, а адрес имеет .getZipCode () и т.д. - и не заботится о том, какие таблицы вызываются для хранения этих данных. .

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

Масштабируемость является интересным моментом - большинство веб-сайтов, требующих огромной масштабируемости (например, facebook, livejournal, flickr), как правило, используют аскетический подход к БД, когда БД используется как можно реже, а проблемы масштабируемости решаются путем кэширования, особенно за счет использования ОЗУ. На http://highscalability.com/ есть несколько интересных статей об этом.


2
Масштабируемость корпоративных приложений не всегда решается с помощью кэширования, так как большая часть этого часто изменяет транзакционные данные в таблицах с миллионами строк. Я вижу facebook et. al. как веб-сайты большого объема, где основная часть обслуживает так много веб-запросов.
Eric Z Beard

4

Есть и другие веские причины для создания объектов сущностей, помимо абстракции и слабой связи. Одна из вещей, которые мне больше всего нравятся, - это строгая типизация, которой нельзя добиться с помощью DataReader или DataTable. Другая причина заключается в том, что, если все сделано правильно, правильные классы сущностей могут сделать код более удобным для обслуживания за счет использования первоклассных конструкций для терминов, зависящих от предметной области, которые, скорее всего, поймет любой, кто смотрит код, а не набор строк с именами полей в них. для индексации DataRow. Хранимые процедуры действительно ортогональны использованию ORM, поскольку многие фреймворки отображения дают вам возможность отображать в sprocs.

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

Я могу понять ваше отвращение к ORM, если ваш опыт в основном состоит из Java EE и CSLA. Возможно, вы захотите взглянуть на LINQ to SQL, который представляет собой очень легкую структуру и в первую очередь является взаимно-однозначным сопоставлением с таблицами базы данных, но обычно требует лишь незначительного расширения, чтобы они были полноценными бизнес-объектами. LINQ to SQL также может сопоставлять объекты ввода и вывода с параметрами и результатами хранимых процедур.

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

Я думаю, что больше ИТ-проектов на предприятиях терпят неудачу из-за невозможности поддержки кода или низкой производительности разработчиков (что может происходить, например, из-за переключения контекста между написанием sproc и написанием приложений), чем из-за проблем с масштабируемостью приложения.


Я думаю, что хорошим компромиссом было бы сопоставление ORM с хранимыми процедурами, за исключением того, что это легко сделать плохо: если вы просто создаете 4 процесса CRUD для каждой таблицы, вы ничего не добьетесь. Можете ли вы сопоставить большие, грубые процессы с сущностями, или это вас ни к чему не приведет?
Eric Z Beard,

В дополнение к операциям CRUD, ORM Microsoft позволяют добавлять методы в классы сущностей, которые сопоставляются непосредственно с любой хранимой процедурой, которую вы хотите передать в нее (при условии, что все типы ввода / вывода сопоставимы).
Марк Сидаде,

3

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


3

Что делать, если вам нужно масштабировать приложение путем балансировки нагрузки более чем одного веб-сервера? Вы можете установить полное приложение на все веб-серверы, но лучшее решение - заставить веб-серверы взаимодействовать с сервером приложений.

Но если нет никаких объектов сущностей, им не о чем будет много говорить.

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

Это экономит время, когда дело доходит до его обслуживания.

Разделяя логику приложения от логики представления и доступа к данным и передавая DTO между ними, вы отделяете их. Позволяя им меняться независимо.


3
Многие люди поднимают вопрос о разделении и позволяют изменять один слой, не затрагивая другой. Хранимые процедуры делают это лучше любого ORM! Я могу радикально изменить модель данных, и пока процедуры возвращают одни и те же данные, ничего не ломается.
Eric Z Beard,

2
На мой взгляд, хранимые процедуры И модель сущности не исключают друг друга. Хранимые процедуры могут предоставить механизм для хранения вашей модели сущностей. Возникает вопрос: работает ли ваша бизнес-логика с сущностями или напрямую обращается к хранимым процедурам?
jbandi 05

3

Этот пост на comp.object может показаться вам интересным.

Я не утверждаю, что согласен или не согласен, но это интересно и (я думаю) имеет отношение к этой теме.


Это отличный пост. Подытоживает мои мысли об ORM почти идеально.
Эрик З. Бирд

3

Вопрос: как вы обрабатываете отключенные приложения, если вся ваша бизнес-логика находится в ловушке базы данных?

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

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

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


2

@jdecuyper, я часто повторяю про себя одну максиму: «Если вашей бизнес-логики нет в вашей базе данных, это всего лишь рекомендация». Я думаю, что Пол Нильсон сказал это в одной из своих книг. Уровни приложений и пользовательский интерфейс приходят и уходят, но данные обычно живут очень долго.

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


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

И почему вы всегда должны использовать уровень обслуживания, чтобы справляться с несоответствием между миром объектов и миром отношений. Проникновение бизнес-логики на каждый уровень, безусловно, НЕ неизбежно.
cdaq

2

В последнее время я много думал об этом; Я был активным пользователем CSLA в течение некоторого времени, и мне нравится чистота заявлений о том, что «вся ваша бизнес-логика (или, по крайней мере, насколько это возможно) инкапсулирована в бизнес-объекты».

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

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

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

При этом, как уже отмечалось выше, не существует «идеального дизайна», инструмент должен соответствовать работе. Но использование бизнес-сущностей действительно может помочь в обслуживании и продуктивности, поскольку вы знаете, куда идти, чтобы изменить бизнес-логику, а объекты могут моделировать концепции реального мира интуитивно понятным способом.


2

Эрик,

Никто не мешает вам выбрать желаемую структуру / подход. Если вы собираетесь пойти по пути «управляемых данными / хранимыми процедурами», то обязательно сделайте это! Особенно, если это действительно помогает вам доставлять ваши приложения в срок и в срок.

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

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

Единственное реальное правило здесь - это последовательность слов . Никто не мешает вам ориентироваться на БД. Никто не мешает вам выполнять структурированные (то есть функциональные / процедурные) программы старой школы. Черт, никто никому не мешает писать код в стиле COBOL. НО приложение должно быть очень, очень последовательным, идя по этому пути, если оно хочет достичь хоть какой-то степени успеха.


Я согласен с последовательностью во всем приложении. Честно говоря, некоторое время назад я изменил направление своего текущего проекта и так и не успел починить 100% исходной модели, что сбивает с толку. Хорошие решения лучше всего принимать заблаговременно.
Eric Z Beard,

Эрик, действительно так. Когда-то я был фанатиком ООП (как и другие участники этой ветки), но я встретил парня, который владеет компанией, которая очень успешно продает приложения на базе БД. Это потрясло мой мир. Я все еще фанат OOP / TDD, но больше не осуждаю DB-ориентированность.
Джон Лимджап,

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

2

Я действительно не уверен, что вы считаете «корпоративными приложениями». Но у меня сложилось впечатление, что вы определяете его как внутреннее приложение, в котором СУБД будет высечена в камне, и система не должна будет взаимодействовать с любыми другими системами, внутренними или внешними.

Но что, если бы у вас была база данных со 100 таблицами, которые равны 4 хранимым процедурам для каждой таблицы только для базовых операций CRUD, это 400 хранимых процедур, которые необходимо поддерживать и не являются строго типизированными, поэтому они подвержены опечаткам и не могут быть протестированы . Что произойдет, когда вы получите нового технического директора, который является евангелистом открытого исходного кода и хочет изменить СУБД с SQL Server на MySql?

Сегодня очень много программного обеспечения, будь то корпоративные приложения или продукты, используют SOA и имеют некоторые требования для предоставления веб-сервисов, по крайней мере, программное обеспечение, с которым я работаю и с которым работал. Используя ваш подход, вы получите доступ к Serialized DataTable или DataRows. Теперь это может считаться приемлемым, если гарантировано, что клиент .NET и находится во внутренней сети. Но когда клиент неизвестен, вам следует стремиться к созданию интуитивно понятного API, и в большинстве случаев вы не захотите раскрывать полную схему базы данных. Я определенно не хотел бы объяснять Java-разработчику, что такое DataTable и как его использовать. Также необходимо учитывать пропускную способность и размер полезной нагрузки, а также сериализованные таблицы данных, наборы данных очень тяжелые.

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

только мои 2 цента


Нет, мое определение корпоративного приложения противоположное. Схема часто меняется, существует множество приложений, использующих базу данных, и она взаимодействует со многими внешними партнерами. В реальном корпоративном приложении вы никогда и никогда не перейдете на другую СУБД. Этого просто не бывает.
Eric Z Beard

И создание 4 процедур для каждой таблицы - плохая практика. Он тесно связывает вас с моделью данных, как сгенерированный sql из ORM, поэтому он ничего вам не покупает. Процессы должны быть крупномасштабными бизнес-операциями, а не только CRUD для каждой таблицы.
Eric Z Beard

Но разве это не ответ? Чем больше кода вам нужно написать, тем больше вам понадобится функций для поддержки крупномасштабного программирования: инкапсуляция, ввод строк, рефакторинг, сложный стиль и проверка ошибок и т. Д .; Java и .NET имеют широкую поддержку в этой области, а языки хранимых процедур - нет.
reinierpost 01

2

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

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

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

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

Я предполагаю, что объектно-ориентированный подход, должно быть, появился, когда люди обнаружили, что другие аспекты реальности сложнее смоделировать, чем бухгалтерский учет (который уже является моделью). ОО стало очень успешной идеей, но настойчивость ОО-данных относительно слабо развита. У RDB / Бухгалтерский учет были легкие победы, но объектно-ориентированный подход - гораздо более обширная область (в основном все, что не является бухгалтерским учетом).

Многие из нас хотели использовать объектно-ориентированный подход, но нам все еще нужно безопасное хранение наших данных. Что может быть безопаснее, чем хранить наши данные так же, как это делает уважаемая система бухгалтерского учета? Это заманчивые перспективы, но все мы сталкиваемся с одними и теми же подводными камнями. Очень немногие удосужились подумать о настойчивости объектно-ориентированного подхода по сравнению с массированными усилиями индустрии RDB, которая извлекла выгоду из традиций и положения бухгалтерского учета.

Prevayler и db4o - это некоторые предложения, я уверен, что есть и другие, о которых я не слышал, но ни один из них, похоже, не вызвал такого внимания, как, скажем, спячка.

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

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

Я буду счастлив, когда пропасть закроется навсегда. Я думаю, решение придет, когда Oracle запустит что-то вроде «Oracle Object Instance Base». Чтобы действительно завоевать популярность, у него должно быть обнадеживающее имя.


Я не думаю, что вам нужен ORM, чтобы объектно ориентированный объект считался полезным. Я использую хранимые процедуры и пишу в своем коде множество статических вспомогательных классов, но эти классы построены на огромной платформе .NET, которая представляет собой фантастический набор объектов.
Эрик Зи Берд,

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

1

На данный момент не так много времени, но просто не в порядке ...

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

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

Вот несколько вещей, которые вы должны иметь в виду (IMO):

  1. Сгенерированный код SQL плохой (за исключениями). Извините, я знаю, что многие люди думают, что это огромная экономия времени, но я никогда не находил систему, которая могла бы генерировать более эффективный код, чем то, что я мог бы написать, и часто код просто ужасен. Вы также часто в конечном итоге создаете тонну кода SQL, который никогда не используется. Исключением являются очень простые шаблоны, например, таблицы поиска. Тем не менее, многие люди увлекаются этим.
  2. Entities <> Tables (или даже объекты логической модели данных обязательно). Модель данных часто имеет правила данных, которые должны применяться как можно ближе к базе данных, которые могут включать правила, касающиеся того, как строки таблицы связаны друг с другом, или другие аналогичные правила, которые слишком сложны для декларативного RI. Их следует обрабатывать в хранимых процедурах. Если все ваши хранимые процедуры являются простыми процедурами CRUD, вы не сможете этого сделать. Вдобавок ко всему, модель CRUD обычно создает проблемы с производительностью, поскольку не сводит к минимуму круговые обходы по сети в базу данных. Часто это самое узкое место в корпоративном приложении.

Согласился на сгенерированный SQL. Это всегда вызывает больше проблем, чем решает. И я очень против простого создания слоя CRUD с сохраненными процедурами. Процессы должны быть как можно более крупными. Не уверен, как вы определяете «одно приложение».
Eric Z Beard,

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

1

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

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


1

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

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

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

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


0

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

Что бы вы ни делали, это не ООП. В этом нет ничего плохого, это просто не ООП, и нет смысла применять свои решения ко всем остальным проблемам.


Данные всегда на первом месте. Это причина, по которой у вас вообще есть компьютерная программа. Таким образом, «сначала база данных», возможно, единственный действительный подход к разработке приложений.
gbjbaanb

0

Интересный вопрос. Пара мыслей:

  1. Как бы вы провели модульное тестирование, если бы вся ваша бизнес-логика была в вашей базе данных?
  2. Разве изменения в структуре вашей базы данных, особенно те, которые затрагивают несколько страниц в вашем приложении, не будут серьезной проблемой для внесения изменений во всем приложении?

0

Хороший вопрос!

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

Например,

Объект AnswerIterator создает объекты AnswerIterator.Answer. Под капотом он перебирает оператор SQL для получения всех ответов и еще один оператор SQL для получения всех связанных комментариев. Но при использовании итератора я просто использую объект Answer с минимальными свойствами для этого контекста. С небольшим количеством скелетного кода это становится почти тривиальным.

Я обнаружил, что это хорошо работает, когда мне нужно работать с огромным набором данных, и когда все сделано правильно, это дает мне небольшие временные объекты, которые относительно легко тестировать.

По сути, это тонкая оболочка поверх материала Database Access, но все же дает мне возможность абстрагироваться, когда мне нужно.


0

Объекты в моих приложениях, как правило, связаны с базой данных один к одному, но я нахожу, что использование Linq To Sql, а не sprocs значительно упрощает написание сложных запросов, особенно возможность их создания с использованием отложенного выполнения. например, из r в Images.User.Ratings where и т. д. Это избавляет меня от попыток разработать несколько операторов соединения в sql, а наличие Skip & Take для разбиения на страницы также упрощает код, вместо того, чтобы вставлять код row_number и 'over'.


В этом есть большая опасность. Большинство сложных запросов приходится полностью переписывать администраторам баз данных, чтобы масштабировать их. Никакая настройка индекса не может сделать то, что иногда может сделать изменение запроса. Этот тип Linq2Sql чрезвычайно тесно связан.
Eric Z Beard,

0

Зачем останавливаться на объектах сущности? Если вы не видите значение с объектами сущности в приложении корпоративного уровня, просто сделайте доступ к данным на чисто функциональном / процедурном языке и подключите его к пользовательскому интерфейсу. Почему бы просто не вырезать весь ОО "пух"?


Я не считаю ОО "вздором". Просто за последнее десятилетие или около того MSFT, Sun и другие написали 99% объектов, которые нам когда-либо понадобятся. То, что я пишу множество статических классов поверх фреймворка, не означает, что я не использую объектно-ориентированный подход.
Eric Z Beard,
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.