Я погружаюсь в дизайн, управляемый доменом (DDD), и хотя я углубляюсь в это, есть некоторые вещи, которые я не понимаю. Насколько я понимаю, главное - это отделить доменную логику (бизнес-логику) от инфраструктуры (БД, файловая система и т. Д.).
Что мне интересно, так это то, что происходит, когда у меня возникают очень сложные запросы, такие как запрос на расчет материальных ресурсов? В таких запросах вы работаете с тяжелыми операциями над множествами, для которых и был разработан SQL. Выполнять эти вычисления на уровне домена и работать с большим количеством наборов в нем - все равно что отбросить технологию SQL.
Выполнение этих вычислений в инфраструктуре также не может произойти, потому что шаблон DDD позволяет вносить изменения в инфраструктуру, не изменяя уровень домена и не зная, что MongoDB не обладает такими же возможностями, как, например, SQL Server, что не может произойти.
Это ловушка DDD?
источник
... is like throwing away the SQL technology
То, что конкретная технология может что-то сделать, не означает, что это лучший выбор. Это неподтвержденное свидетельство, но я встречал слишком много компаний, которые хранили бизнес-логику в базе данных и уходят от нее из-за долговременных проблем с обслуживаемостью, которые она вызывает. Упрощенно, но базы данных предназначены для хранения данных, а языки программирования предназначены для преобразования данных. Я бы не хотел использовать БД для бизнес-логики больше, чем пытаться использовать свое приложение для непосредственного хранения моих данных.Ответы:
В наши дни вы, скорее всего, увидите, что операции чтения (запросы) обрабатываются иначе, чем операции записи (команды). В системе со сложным запросом сам запрос вряд ли пройдет через модель предметной области (которая в первую очередь отвечает за поддержание согласованности записей ).
Вы абсолютно правы в том, что мы должны передавать в SQL то, что является SQL. Поэтому мы разработаем модель данных, оптимизированную для операций чтения, и запрос этой модели данных обычно будет содержать путь к коду, который не включает модель домена (за возможным исключением некоторой проверки входных данных - обеспечение того, что параметры в запросе разумны).
источник
Это основа недоразумения: цель DDD не состоит в том, чтобы разделить вещи по жесткой линии, например, «это на сервере SQL, поэтому не должно быть BL», цель DDD - разделить домены и создать барьеры между они позволяют внутренним элементам домена быть полностью отделенными от внутренних элементов другого домена и определять общие внешние элементы между ними.
Не думайте, что «быть в SQL» - это барьер BL / DL - это не то, что есть. Вместо этого думайте, что «это конец внутреннего домена», как барьер.
Каждый домен должен иметь внешние API-интерфейсы, позволяющие ему работать со всеми другими доменами: в случае уровня хранения данных он должен иметь действия чтения / записи (CRUD) для объектов данных, которые он хранит. Это означает , что само по себе SQL не является на самом деле барьер,
VIEW
иPROCEDURE
компоненты. Вы никогда не должны читать непосредственно из таблицы: это подробности реализации DDD говорит нам, что, как внешний потребитель, мы не должны беспокоиться.Рассмотрим ваш пример:
Это именно то, что должно быть в SQL, и это не является нарушением DDD. Это то, для чего мы сделали DDD . С этим вычислением в SQL это становится частью BL / DL. Что бы вы сделали, это использовали бы отдельное представление / хранимую процедуру / что-что-у-вас и держали бизнес-логику отдельно от уровня данных, так как это ваш внешний API. Фактически, ваш уровень данных должен быть еще одним DDD Domain Layer, где ваш уровень данных имеет свои собственные абстракции для работы с другими уровнями домена.
Это еще одно недоразумение: в нем говорится, что детали реализации внутри могут меняться без изменения других уровней домена. В нем не сказано, что вы можете просто заменить целую часть инфраструктуры.
Опять же, имейте в виду, что DDD скрывает внутренние компоненты с четко определенными внешними API. Где находятся эти API - это совершенно другой вопрос, и DDD этого не определяет. Он просто определяет, что эти API существуют и никогда не должны изменяться .
DDD не настроен так, чтобы вы могли произвольно заменить MSSQL на MongoDB - это два совершенно разных компонента инфраструктуры.
Вместо этого давайте воспользуемся аналогией для определения DDD: газ против электромобилей. У обоих автомобилей есть два совершенно разных метода создания тяги, но у них одинаковые API: включение / выключение, дроссель / тормоз и колеса для движения автомобиля. DDD говорит, что мы должны иметь возможность заменить двигатель (бензиновый или электрический) в нашем автомобиле. Это не говорит о том, что мы можем заменить автомобиль на мотоцикл, и это фактически то, что MSSQL → MongoDB.
источник
Если вы когда-либо были в проекте, где организация, платящая за размещение приложения, решает, что лицензии на уровне базы данных слишком дороги, вы по достоинству оцените простоту, с которой вы можете перенести свою базу данных / хранилище данных. Учитывая все обстоятельства, хотя это происходит, это случается не часто .
Вы можете получить лучшее из обоих миров, так сказать. Если вы рассматриваете выполнение сложных функций в базе данных как оптимизацию, то вы можете использовать интерфейс для внедрения альтернативной реализации вычисления. Проблема в том, что вы должны поддерживать логику в нескольких местах.
Отклонение от архитектурного образца
Когда вы сталкиваетесь с трудностями при чисто шаблонном применении или отклонении в какой-либо области, тогда вам нужно принять решение. Шаблон - это просто шаблонный способ сделать что-то, чтобы помочь организовать ваш проект. На этом этапе нужно время, чтобы оценить:
Вы обнаружите, что некоторые архитектурные шаблоны хорошо подходят для 80-90% вашего приложения, но не так сильно для оставшихся битов. Случайное отклонение от предписанного шаблона полезно по причинам производительности или логистики.
Однако, если вы обнаружите, что ваши кумулятивные отклонения составляют более 20% от архитектуры вашего приложения, это, вероятно, просто плохое соответствие.
Если вы решите продолжать следовать архитектуре, сделайте себе одолжение и укажите, где и почему вы отклонились от предписанного способа действий. Когда в вашей команде появляется новый увлеченный участник, вы можете указать им на эту документацию, которая включает измерения производительности и обоснования. Это уменьшит вероятность повторных запросов для устранения «проблемы». Эта документация также поможет устранить необузданные отклонения.
источник
Логика манипулирования множеством, в которой хорошо работает SQL, без проблем может быть интегрирована с DDD.
Скажем, например, мне нужно знать некоторую совокупную стоимость, общее количество продуктов по типу. Легко запустить в SQL, но медленно, если я загружаю каждый продукт в память и добавляю их все.
Я просто представляю новый объект Domain,
и метод в моем хранилище
Конечно, может быть, теперь я полагаюсь на то, что у моей БД есть определенные способности. Но у меня все еще есть техническое разделение, и пока логика проста, я могу утверждать, что это не «бизнес-логика»
источник
Query
параметры.repository.find(query);
, Я читал то же самое, но сSpecs. That opens a door to leave
Query` в качестве абстракции и /QueryImpl
или реализации конкретного запроса на уровне инфраструктуры.I know some people do that
некоторые люди являются Pivotal и его основой. SpringFramework имеет много этого :-). В любом случае, как предположил @VoiceOfUnreason, ключом к DDD является поддержание согласованности записей. Я не уверен в том, чтобы заставить дизайн использовать доменные модели, для которых единственной целью является запрос или параметризация запросов. Это может быть реализовано вне домена с помощью структур данных (pocos, pojos, dtos, преобразователи строк и т. Д.).Один из возможных способов решения этой дилеммы - думать о SQL как о языке ассемблера: вы редко, если вообще используете код непосредственно на нем, но там, где важна производительность, вы должны уметь понимать код, созданный вашим C / C ++ / Golang / Rust компилятор и, возможно, даже написать крошечный фрагмент в сборке, если вы не можете изменить код на языке высокого уровня для получения желаемого машинного кода.
Точно так же в области баз данных и SQL различные библиотеки SQL (некоторые из которых являются ORM ), например SQLAlchemy и Django ORM для Python, LINQ для .NET, предоставляют абстракции более высокого уровня, но по возможности используют сгенерированный код SQL для достижения производительности. Они также обеспечивают некоторую переносимость в отношении используемой БД, возможно, с разной производительностью, например, на Postgres и MySQL, из-за некоторых операций, использующих более оптимальный SQL для конкретной БД.
Как и в случае с языками высокого уровня, очень важно понимать, как работает SQL, даже если нужно просто переупорядочить запросы, выполняемые с вышеупомянутыми библиотеками SQL, для достижения желаемой эффективности.
PS Я бы предпочел сделать комментарий, но у меня нет достаточной репутации для этого.
источник
Как обычно, это одна из тех вещей, которая зависит от ряда факторов. Это правда, что с SQL можно многое сделать. Есть также проблемы с его использованием и некоторые практические ограничения реляционных баз данных.
Как отмечает в комментариях Джаред Гогуэн, SQL может быть очень сложно протестировать и проверить. Основные факторы, которые приводят к этому, - то, что это не может (вообще) быть разложено на компоненты. На практике сложный запрос должен рассматриваться в целом. Еще одним осложняющим фактором является то, что поведение и правильность SQL сильно зависят от структуры и содержания ваших данных. Это означает, что тестирование всех возможных сценариев (или даже определение того, что они есть) часто невозможно или невозможно. Рефакторинг SQL и модификация структуры базы данных также проблематичны.
Другим важным фактором, который привел к отходу от SQL, являются реляционные базы данных, которые имеют тенденцию масштабироваться только по вертикали. Например, когда вы строите сложные вычисления в SQL для запуска в SQL Server, они будут выполняться в базе данных. Это означает, что вся эта работа использует ресурсы в базе данных. Чем больше вы делаете в SQL, тем больше ресурсов понадобится вашей базе данных с точки зрения памяти и процессора. Часто это менее эффективно делать в других системах, но практического ограничения количества дополнительных машин, которые вы можете добавить к такому решению, нет. Этот подход менее дорогой и более отказоустойчивый, чем создание огромного сервера баз данных.
Эти проблемы могут относиться или не относиться к данной проблеме. Если вы можете решить вашу проблему с помощью доступных ресурсов базы данных, возможно, SQL подойдет для вашего проблемного пространства. Вы должны учитывать рост, однако. Это может быть хорошо сегодня, но через несколько лет стоимость добавления дополнительных ресурсов может стать проблемой.
источник
Позвольте мне сначала прояснить несколько заблуждений.
DDD это не образец. И это действительно не предписывает образцы.
В предисловии к книге DDD Эрика Эвана говорится:
Таким образом, это подход к разработке программного обеспечения и моделированию предметной области, а также некоторый технический словарь, который поддерживает эти действия (словарь, который включает в себя различные концепции и шаблоны). Это также не что-то совершенно новое.
Следует также помнить, что модель предметной области - это не ОО-реализация, которую можно найти в вашей системе - это всего лишь один из способов выразить ее или выразить некоторую ее часть. Модель предметной области - это способ решения проблемы, которую вы пытаетесь решить с помощью программного обеспечения. Это то, как ты понимаешь и воспринимаешь вещи, как ты о них говоришь. Это концептуально . Но не в каком-то смутном смысле. Это глубоко и утонченно, и является результатом тяжелой работы и сбора знаний. Он дополнительно уточняется и, вероятно, со временем эволюционирует и включает в себя соображения реализации (некоторые из которых могут ограничивать модель). Это должно быть разделено всеми членами команды (и участвуют эксперты в области), и он должен определять, как вы внедряете систему, чтобы система точно отражала ее.
Ничто в этом не является про- или анти-SQL, хотя разработчики ОО, возможно, в целом лучше выражают модель на языках ОО, и выражение многих концепций предметной области лучше поддерживается ООП. Но иногда части модели должны быть выражены в другой парадигме.
Ну, вообще говоря, здесь есть два сценария.
В первом случае некоторый аспект домена действительно требует сложного запроса, и, возможно, этот аспект лучше всего выражен в парадигме SQL / реляционная, поэтому используйте соответствующий инструмент для работы. Отразите эти аспекты в своем доменном мышлении и языке, используемом для передачи концепций. Если домен сложный, возможно, это часть субдомена с собственным ограниченным контекстом.
Другой сценарий состоит в том, что осознанная необходимость выражать что-либо в SQL является результатом ограниченного мышления. Если человек или команда всегда были ориентированы на базу данных в своем мышлении, им может быть трудно, просто из-за инерции, увидеть другой подход к вещам. Это становится проблемой, когда старый способ не удовлетворяет новым потребностям и требует определенного мышления из коробки. DDD, как подход к дизайну, частично посвящен тому, как найти выход из этой коробки путем сбора и распространения знаний о предметной области. Но все, кажется, игнорируют эту часть книги и сосредотачиваются на некоторых из перечисленных технических терминов и шаблонов.
источник
Сиквел стал популярным, когда память была дорогой, потому что реляционная модель данных предоставляла возможность нормализовать ваши данные и эффективно хранить их в файловой системе.
Теперь память относительно дешева, поэтому мы можем пропустить нормализацию и сохранить в том формате, в котором мы ее используем, или даже скопировать много одинаковых данных ради скорости.
Рассматривайте базу данных как простое устройство ввода-вывода , которое несет ответственность за хранение данных в файловой системе - да, я знаю, это сложно представить, потому что мы написали множество приложений с важной бизнес-логикой, записанной в запросах SQL, - но просто попытайтесь представить, что SQL Server это просто еще один принтер.
Вы бы встроили генератор PDF в драйвер принтера или добавили триггер, который будет печатать страницу журнала для каждого заказа на продажу, распечатанного с нашего принтера?
Я предполагаю, что ответ будет отрицательным, потому что мы не хотим, чтобы наше приложение было связано с конкретным типом устройства (даже не говоря об эффективности такой идеи)
В 70-90-х годах базы данных SQL были эффективными, а теперь? - Не уверен, что в некоторых случаях асинхронный запрос данных будет возвращать требуемые данные быстрее, чем множественные объединения в запросе SQL.
SQL не был разработан для сложных запросов, он был разработан для эффективного хранения данных, а затем предоставлял интерфейс / язык для запроса хранимых данных.
Я бы сказал, что построение вашего приложения на основе реляционной модели данных со сложными запросами - это злоупотребление движком базы данных. Конечно, поставщики ядра СУБД счастливы, когда вы тесно связываете свой бизнес с их продуктом - они будут более чем рады предоставить больше возможностей, которые укрепят эту связь.
источник