Таблицы поиска: являются ли они утечкой в ​​модели предметной области?

10

Вы строите систему, которая отслеживает компании. Эти компании имеют контакты. Эти контакты часто являются специалистами, которые отвечают только на некоторые типы вопросов, таких как выставление счетов / оплата, продажи, заказы и поддержка клиентов.

Используя доменно-управляемый дизайн и архитектуру Onion, я смоделировал это со следующими типами:

  • Компания
    • Имеет контакты
  • контакт
    • Имеет типы контактов
  • ContactType (enum)
  • CompanyRepository (интерфейс)
  • EFCompanyRepository (определяется во внешней сборке, использует EntityFramework, реализует CompanyRepository)

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

Сторона A: Lean DDDers:

  • Задача домена - определить, какие контактные типы действительны для контакта. Добавление таблицы в базу данных для проверки того, что неизвестные типы контактов не сохранены, является признаком домена с утечкой. Это распространяет логику слишком далеко.
  • Добавление статической таблицы в базу данных и соответствующего кода расточительно. В этом приложении база данных решает одну проблему: сохраните вещь и верните ее мне. Написание дополнительной таблицы и соответствующего кода CRUD расточительно.
  • Изменение стратегии для настойчивости должно быть как можно проще. Это более вероятно, чтобы изменить эти бизнес-правила. Если я решу, что SQL Server стоит слишком дорого, мне не нужно будет перестраивать всю проверку, которую я включил в свою схему.

Сторона Б: Традиционалисты [это, вероятно, не честное имя. DBCentrists?]:

  • Это плохая идея иметь данные в базе данных, которые не имеют смысла без чтения кода. Отчеты и другие потребители должны сами повторить список значений.
  • Это не так много кода, чтобы загрузить словари типа БД по требованию. Не беспокойся об этом.
  • Если источником этого является код, а не данные, мне придется развертывать биты вместо простого сценария SQL при его изменении.

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

Нарисовалась
источник
Я предпочитаю иметь таблицы поиска в базе данных и иметь код (шаблоны T4 в .NET), который генерирует для меня перечисления на основе таблиц поиска в моем коде приложения.
программист
@JasonHolland Действительно ли шаблон T4 выполняет запрос? В противном случае я не уверен, как он генерирует больше, чем пустое перечисление с ожидаемым именем.
Дрю
2
да, он выполняет запрос. Взгляните на developerhandbook.com/c-sharp/t4-templates-for-lookup-tables и erraticdev.blogspot.com/2011/01/…
программист
Для таблицы со статическими значениями, сколько CRUD-кода вам нужно написать? Сценарий это и будет сделано.
Джефф
2
Традиционный аргумент CRUD о том, что «ну, это не имеет смысла для отчетности», не является началом. Как только вы вводите какую-то другую ответственность, которую система несет (например, отчетность), вы обнаруживаете бизнес-требование, которое необходимо выполнять надлежащим образом. База данных предназначена для хранения и загрузки приложений в защищенном состоянии; разрешение на создание отчетов создает связь между вашим приложением и людьми, которым нужны отчеты. Если DDD о чем-то, то это о разделении этих контекстов.
Мэтт

Ответы:

4

Приняв архитектуру DDD и onion, вы решили, что база данных является второй по сравнению с вашей моделью домена. Это означает, что никто не будет выполнять операции с базой данных, кроме модели. Если традиционалистам это не нравится, они должны были бы возражать против использования DDD.

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

Euphoric
источник
2

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

Тем не менее, я думаю, что ваши DBCentrists скучают по лодке. Разработчики доменов говорят, что им нужно постоянное хранилище. «Отчеты и другие потребители» нуждаются в том, что они могут запросить - что-то с приличными индексами, как было отмечено в комментариях.

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

Ключевое слово для поиска: CQRS.

VoiceOfUnreason
источник
1

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

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

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

Не уверен, что я бы охарактеризовал это как разницу между DDD и Trad. На мой взгляд, это лучше, чем централизатор базы данных и код

Ewan
источник
Интересно, есть ли в самих базах такая функция перечисления в эти дни
herzmeister
Я думаю, это будет зависеть от БД, с MSSQL можно делать всякие сумасшедшие вещи CLR. Но я твердо придерживаюсь позиции «БД плохой, код хороший», когда дело доходит до таких вещей
Эван
@herzmeister <3 PostgreSQL postgresql.org/docs/9.4/static/datatype-enum.html , Ewan БД - это код, когда вы включаете хранимые процедуры. (PLv8 замечательный).
Сирисян
@Sirisian вы знаете, что это смешивает вещи? У меня похожий вопрос. "Это масштабируется?"
Эван
Вы имеете в виду, что это делает перекрестный продукт, чтобы превратить перечисление в строку? Возможно нет. Я не уверен, как это реализовано, но это быстрее, чем использование отдельной таблицы. Это масштабируется. Нашел это также: stackoverflow.com/questions/2318123/… Похоже, действительная оценка 5 лет спустя. (Я склонен писать программы, тесно связанные с PostgreSQL, поэтому я использую все функции, но не каждый может это сделать).
Сирисян
0
  • Пока вы используете реляционную базу данных, вы должны поддерживать таблицы в нормальных пределах. Нормализация помогает предотвратить вставку и обновление аномалий.
  • Отношение «одно приложение <-> одна база данных» более не распространено, несколько приложений могут использовать несколько баз данных, а одна база данных может использоваться несколькими приложениями, поэтому использование базы данных, обеспечивающей ссылочную целостность в максимально возможной степени, является хорошим.
  • СУРБД ваш друг.
  • Вместо этого вы можете использовать хранилище значений ключей и делать все в коде.
Тулаинс Кордова
источник