Уровень приложений, вызывающий функции базы данных. Плохая архитектура?

11

Сценарий:

  • Стек: Java, Spring, Hibernate.
  • Модель: клиент-серверное приложение.
  • Шаблон: Модель-Вид-Контроллер (MVC).

Классы Service Layer имеют три поведения:

  1. Некоторые сервисы имеют бизнес-правило внутри методов и делегируют постоянство приложению. Подобно:

    EntityManager.save (юридическое лицо);

  2. Некоторые сервисы просто вызывают функцию базы данных (передавая параметры)

    CallableStatement cls = con.prepareCall ("{call databaseFunction (args)}");

  3. Некоторые сервисы имеют методы с обоим поведением.

Мои вопросы:

  1. Есть ли проблема в том, чтобы прикладные службы вызывали функции базы данных напрямую? Разве это не считается плохой практикой? Какая модель архитектуры будет применима к такому проекту?
  2. Есть ли какая-либо проблема в том, что поведение поведения в одной и той же службе? Такие как транзакции и последовательность?
  3. В случае обслуживания, делает ли эта инкапсуляция неясным для разработчика, что он также должен изменить функции в базе данных? Как этого избежать?
  4. Этот сценарий встречается в других приложениях по всему миру или это просто архитектурная ошибка?
linuxunil
источник
Этот вопрос похож, но не точно такой же. Softwareengineering.stackexchange.com/questions/180012/…
Джон Рейнор

Ответы:

7

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

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

Какая модель архитектуры будет применима к такому проекту?

Смотрите комментарий ниже.

Есть ли какая-либо проблема в том, что поведение поведения в одной и той же службе? Такие как транзакции и последовательность?

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

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

Конечно, это так.

Как этого избежать?

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

Этот сценарий встречается в других приложениях по всему миру или это просто архитектурная ошибка?

Я думаю, что в нашем мире все происходит;)

Владислав Раструсный
источник
Если я правильно понимаю, может быть техническая проблема, заключающаяся в том, что если обновления происходят в функциях / сохраненных процессах, а также через ORM, о состояниях данной транзакции очень трудно рассуждать. Хотя приложение может работать в своем текущем состоянии, небольшие изменения могут привести к серьезным проблемам. Мой опыт работы с Hibernate заключается в том, что если вы не позволите ему управлять всем набором таблиц, с которыми он работает, у вас возникнет множество досадных проблем.
JimmyJames
хороший и лаконичный ответ. SRP был первым, что пришло мне в голову, когда я впервые посмотрел на код. Некоторые сотрудники говорят, что метод не нарушает SRP из-за того, что он вызывает только функцию базы данных. Но некоторые из этих функций делают выбор, вставку и обновление. Так это нарушает СРП или нет? (может быть, это другой вопрос, который нужно обсуждать отдельно?)
linuxunil
1
+1 за эту строчку я думаю в нашем мире все происходит;)
linuxunil
@linuxunil SRP следует уважать на всех уровнях архитектуры. В моем случае я имел в виду SRP на уровне сервиса, а не на уровне метода. @ JimmyJames Да. Большинство ORM плохо работают с хранимыми процедурами. Но иногда хранимый процесс необходим.
Владислав Раструсный
3

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

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

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

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

Дж. Пичардо
источник
Не уверен, почему за это проголосовали. Этот ответ рекомендует разделять код, который имеет дело с различными проблемами . Чувствуется, как руководитель программирования здесь ... не уверен, что это такое ... Человек. Если бы я только мог придумать имя. +1 Кстати
Грег Бургхардт
Разве это не один из твердых принципов?
J. Pichardo
3
Номер «S» в ТВЕРДОГЕ является S Ingle ответственности принципала (SRP). Но разделение проблем, которое вы рекомендуете, является веской причиной для отделения служебной логики от логики доступа к данным. В другом ответе Владислава упоминается Принцип единой ответственности. Откровенно говоря, SRP и разделение проблем хорошо сочетаются друг с другом, как вино и сыр.
Грег Бургхардт