Pull to refresh

Comments 10

Честно говоря, еще когда читал Эванса несколько удивлялся — зачем столько внимания уделяется очевидным вещам. У меня к тому времени как-то очень естественно и без привлечения литературы сложился подход очень близкий к DDD, только я не знал что он так называется. Этот подход мне казался настолько естественным, что я и предположить не мог, что можно сознательно делать по другому…
Но жизнь показала, что в ней есть место всякому…
В последнее время часто встречаю молодых разработчиков, которые сходу мыслят и пишут в терминах используемых фреймворков. Им даже в голову не приходит выделить уровень абстракции. Для них DDD, наверное, действительно звучит как откровение свыше. :-)
хорошая абстракция и их взаимосвязи помогает структурировать разрозненные знания в голове
не кто не спорит, что здесь люди умные, но разговаривать надо на одном языке и понимать термины единым образом.
Интересно то, что доменная модель здесь выставлена, как ограничение. То есть у вас может быть доменная модель, воплощенная в структуре базы данных, например, но при этом архитектура всего приложения может не соответствовать DDD. Подразумевать модель недостаточно, надо воплотить ее в коде.
Пару лет назад открыл для себя ддд, с тех пор — только он. Мощнейшая штука, незаменима в сложных приложениях
Спасибо за статью, некоторые вещи встали на свои места, чего не случилось после Фаулера.

Как вы считаете, реально ли постепенно внедрять DDD в ИС с уже давно сформированным набором сущностей(таблиц)? Т.е. не прописывать полностью предметную область в объектах, а делать это постепенно, чтобы не попасть на полную переработку?

Вопрос второй: есть такие задачи, которые гораздо проще решать именно в терминах рекордсетов и полей таблиц: например отображение данных в таблицах, отчеты, редкатирование каких-то статических справочников. Ведь эти задачи можно решить довольно быстро, оперируя именно терминами, лежащими ниже уровня предметной области? Этично ли в одном приложении использовать и DDD и RecordSet'ы и какие проблемы можно получить при таком подходе?

И третье. Реляционные базы за 20 лет развития обрели огромное количество высокооптимизированных операций работы с данными, которые не реализуются ни в одном ORM. Язык SQL создан именно для манипулирования сложнорганизованными структурами данных и в целом ряде задач оказывается на порядки удобнее, быстрее в работе и разработке чем решение на основе DDD. Логично было бы использовать всю мощь SQL для таких задач, но как не вступить в противоречие с задачами, которые следует решать в терминах предметной области?
1. Реально. Тут как с рефакторингом — постепенно выделяете один модуль ИС за другим, изолируете доменную логику, переписываете. Если нет тестов — сначала пишете их (желательно крупнокалиберные, интеграционные, чтобы быть уверенным что рефакторинг такого масштаба не нарушил чего-либо). Но нужно быть готовым к существенным затратам времени — тут нужно сделать для себя выбор: иногда поддерживать не очень хорошо написанную систему проще чем переписывать (пусть по частям) ее «по-правильному». Если же в дальнейшем планируется ее серьезная доработка, дописывание функционала — то думаю да, это того стоит. Кстати для работы с legasy-системами в контексте DDD хорошо подходит NHibernate. Эта ORM позволяет очень гибко настраивать маппинг так, что можно будет построить правильную объектную модель не меняя (или почти не меняя) существующую структуру БД.

2. Такие задачи решаются в терминах DDD довольно просто. Для построения отчетов делаются специальные классы — DTO (Data transfer objects), по сути объектные аналоги датасетов. Эти DTO нужны только для компоновки и переноса данных наверх, в UI. Не вижу ничего плохого в использовании вместо DTO датасетов. Если данные, передаваемые в UI, в дальнейшем не меняются, то и беспокоиться о них не стоит — компонуете как нужно отчетам и забываете про них.

3. Было бы неплохо рассмотреть конкретные примеры. Как правило правильно построенная доменная модель + NHibernate решают все эти проблемы
2. Про отчеты понятно, хотя Фаулер, например, сильно предостерегает против DTO.
2.1 А если редактируемые данные? Представьте, около 100 таблиц без какой-либо специальной логики. Только связи и мелкая логика отображения. Все уже работает через Model-View-Controller. Нет никакого желания делать 100 классов, но в другой части программы есть бизнес-логика (проводка документов, например) которая при своей работе потребует как минимум корректного обновления той части с MVC.
3. Вот есть например модуль расчета скидок. В скидках участвует около 30 разных таблиц. Скидка вычисляется огромным SQL-запросом (в хранимой процедуре) в котором около 10 джойнов, масса вложенных запросов, группировки, сортировки. Запрос выстрадан и выглажен до неплохой производительности несмотря на чудовищность. Как это переписать на клиенте в объектах я себе слабо представляю. Это вместо 3 страниц SQLя получится целый проект на много модулей.
4. NHibernate не используем, т.к. все пишется на (внезапно! ) Qt. Я понимаю что Qt не особо подходит для корпоративных приложений, но именно он выбран по ряду причин.
2. Если данные из 100 таблиц отображаются в UI и не редактируются, не уходят обратно в базу, то можно считать их теми же отчетами — берем из БД данные, компонует, отображаем, о дальнейшем не волнуемся. Если же пользователь может менять их и сохранять, то доменная логика существенно усложняется и ее в общем случае лучше изолировать в соответствии с принципами DDD. Тут нужно принять решение как я описывал в п.1: если работа с этими таблицами не слишком сложна, доработка кода не занимает существенного кол-ва времени, то лучше оставить как есть — время затраченное на рефакторинг не окупится, иначе — нужно переписывать.

3. Если это обычный рид-онли sql-запрос — то ок, это не очень хорошо, но в целом нормально. Если же это нерид-онли запрос, то все плохо. Вы жертвуете читабельностью и простотой кода в пользу скорости работы программы и тем самым постепенно загоняете себя в ситуацию когда любые доработки модуля будут занимать неоправданно большое количество времени. Я рекомендую вам написать тесты, развязать модель, выделить доменную логику. Это может занять время, но за счет снижения сложности кода в дальнейшем снизится кол-во багов, уменьшится время, затрачиваемое на доработки. Если весь вопрос в скорости — выделите процесс пересчета скидок в отдельный ждоб (win-сервис), по максимуму используйте асинхронные операции
Спасибо! идея с read-only интересная.

Попробую описать положение дел подробнее:

У нас есть исчерпывающее XML-описание где и как какую таблицу отображать. На основе этого описания строятся динамические модели к которым цепляется опять же динамические View. Т.е. движок приложения ничего не знает о предметной области. Такой подход великолепно работает на задачах простого редактирования и отображения данных. Добавить табличку, или поменять связи очень просто. Для оживления вьюшек еще и скрипты прикручены. Можно вообще наклепать разных XMLек под совершенно разные предметные области.
Динамические модели под собой строят SQL-запросы (опять же динмически) и все это прекрасно работает.
Теперь же надо добавить документы. Т.е. появляется логика их проводки. Так вот для документов мы делаем ORM и объекты предметной области. Которые планируется «подсунуть» динамическим моделям но так, чтобы они по прежнему ничего не знали о предметной области. Т.е. нужна, видимо, сериализация объектов предметной области. Нужно это для того чтобы данные проходили в БД через одно место(в хорошем смысле:)) и не возникало проблем обновления данных в разных подсистемах.

И вот тут-то у меня и возникает когнитивный диссонанс: с одной стороны БД. В ней данные без логики. Мы их десериализуем в объекты предметной области(уровень ORM). Из этих объектов мы в принципе можем захотеть создать какие-то производные объекты (аналог VIEW в БД), накрутить на них поведение какое-то.

Далее одна часть программы(документы) оперирует объектами предметной области, другая эти объекты снова сериализует(!) и использует для простого редактирования.
Страшноватый бутерброд вырисовывается, правда :)?
Не нужно размывать ответственность между разными частями программы. Если вы работаете с документами по-другому (не так как с остальными объектами), то лучше и вьюхи сделать для нее свои, статические.
Универсализация хорошо работает для простых однотипных сущностей, если документы не вписываются в них, то лучше не пытаться их впихнуть туда «насильно» — постройте отдельную модель для работы с ними
Sign up to leave a comment.