TDD - это проектирование кода, руководствуясь тестами.
Таким образом, типичные слои обычно не создаются заранее; они должны слегка появиться через шаги рефакторинга.
Проектирование на основе домена включает в себя множество технических шаблонов, определяющих такие хорошо зарекомендовавшие себя слои, как прикладной уровень, инфраструктурный уровень, доменный уровень, уровень постоянства.
Как начать вести кодовую часть проекта DDD с нуля, как себя вести?
Должен ли я строго позволить дизайну появиться из испытаний, что означает отсутствие разделения интересов (без слоев) и рефакторинга, чтобы соответствовать техническим шаблонам DDD?
Или я должен создать эти пустые слои (приложение, сущности / доменные службы, инфраструктура) и позволить TDD вписаться в каждый из них независимо (используя насмешки для изоляции между уровнями)?
Ответы:
Обязательно просмотрите последние комментарии дяди Боба о роли дизайна в TDD .
Уди Даан: «Боже, как я ненавижу наслоение». Он проводит некоторое время, обсуждая это в своем выступлении CQRS - но по-другому (расслоение начинается в 18-30-х годах)
Я бы написал ваше предложение немного иначе; «DDD признает, что существует ряд проблем, общих для большинства бизнес-приложений, и что решения этих проблем имеют различный срок службы» .
Например, проблемы с доменом, как правило, должны быть гибкими, особенно когда вы настраиваете решение для конкретного бизнеса. В конце концов, домен касается того, как компания ведет бизнес, то есть то, как компания зарабатывает деньги и возможность быстрого улучшения бизнеса - это бесплатный доход.
С другой стороны, вам, вероятно, не нужно часто менять компонент постоянства. Решение для базы данных, которое работало в прошлом выпуске, вероятно, также будет работать в этом выпуске.
Проблемы приложения находятся где-то посередине; они имеют тенденцию быть стабильными, так что пользователям не нужно изучать новое приложение с каждым выпуском.
Кроме того, может быть несколько реализаций, чтобы решить любую проблему. Например, приложению может потребоваться только снимок текущего состояния - достаточно просто сохранить файл на диск. И в ваши первые несколько итераций это может быть все, что нужно для домена. Но в конце концов приходит история, требующая поддержки специальных запросов, и вы понимаете, что настройка реляционной базы данных будет намного проще, чем ее реализация с нуля. И еще есть одна особенность, которая будет лучше работать в графической базе данных.
Тем временем технический директор хочет версию приложения, которая работает на его телефоне; Генеральный директор только что услышал от парня, что публикация API - это большая вещь.
Кроме того, отдел продаж использует другую модель, поэтому предоставьте нам одно и то же приложение с другой моделью. О, но мы много путешествуем, поэтому наша версия должна работать, когда мы не в сети, и синхронизироваться позже ...
Другими словами, вы применяете тактические шаблоны из DDD, не внедряя пустые заполнители и предполагая, что они будут заполнены позже, а вместо этого, распознавая, когда вы пересекаете потоки. «Эй, это постоянный код в моей доменной модели, я не должен рефакторинг еще не завершен. "
источник
Test Driven Development (TDD) - это не дизайн. Это требование, которое влияет на ваш дизайн. Так же, как если бы вы были обязаны быть потокобезопасными, это не дизайн. Опять же, это требование, которое влияет на ваш дизайн.
Если вы радостно игнорируете все другие проблемы проектирования и неукоснительно придерживаетесь правил TDD, не вините TDD, когда ваш код превращается в дерьмо. Это будет проверяемое дерьмо, но это будет дерьмо.
Хорошая вещь в тестируемом дерьме состоит в том, что это рефакторизованное дерьмо, поэтому для некоторых людей этого достаточно. Мы будем фантазировать только тогда, когда это необходимо. Другие ненавидят это и обвиняют TDD в этом. Это твое дело.
Проектирование на основе доменов (DDD) - это то, что вы делаете перед циклом рефакторинга TDD.
DDD - это попытка создать и сохранить пространство в коде, в котором специалист по предметной области, который в значительной степени не знает деталей системы, может понять, как управлять системой. Это делается путем абстрагирования и моделирования проблемной области известным способом.
Система DDD может иметь архитектуру, которая выглядит следующим образом:
Эта архитектура DDD имеет много названий: Clean , Onion , Hexagonal и т. Д.
Вот разрыв, который я вижу у многих людей, когда они смотрят на этот дизайн. Это не конкретно. Я могу следовать этой схеме и никогда не писал ничего, что вы видите на диаграмме здесь. Я вижу, что другие настаивают на том, что должен быть объект прецедента или класс сущностей. Это набор правил, которые говорят вам, с кем вы можете поговорить и как.
Вот и все. Следуйте правилам этого дизайна, и вы можете TDD свое маленькое сердце. TDD не волнует, с кем ты говоришь. Он заботится о том, что все, что делает что-то, может быть доказано, что оно работает или нет одним нажатием кнопки. Нет, что-то где-то сломано. Он говорит вам, что именно сломано.
Все еще расплывчато? Посмотрите на диаграмму
Controler
-Use Case Interactor
-Presenter
в правом нижнем углу. Вот три конкретные вещи, общающиеся друг с другом. Конечно, это DDD, но как добавить сюда TDD? Просто издевайся над конкретным материалом. Ведущий должен получать информацию.PresenterMock
Класс был бы хороший способ проверить , что это то , чего вы ожидали получить. Передайте и драйв , как если бы вы были и у вас есть хороший способ для модульного тестирования , так как насмешка скажет вам , если он получил то , что вы ожидали получить.Use Case Interactor
PresenterMock
Use Case Interactor
Controller
Use Case Interactor
Хорошо посмотри на это. TDD доволен, и нам не пришлось возиться с нашим дизайном DDD. Как это случилось? Мы начали с хорошо отделенного дизайна.
Если вы используете TDD для управления дизайном (а не просто разработкой ), вы получаете дизайн, который отражает усилия, которые вы вложили в него. Если это то, что вы хотите, хорошо. Но это никогда не было то, для чего предназначался TDD. То, что в итоге этого не хватает, конечно, не вина TDD.
TDD не о дизайне. Если вам нужно внести изменения в дизайн, чтобы использовать TDD, у вас больше проблем, чем при тестировании.
источник
TDD гарантирует, что в вашем коде есть все необходимые тестовые примеры, написанные параллельно с разработкой. Это не должно влиять на дизайн высокого уровня. Думайте об этом больше в работе окопов.
DDD - это дизайн высокого уровня, язык между экспертами и инженерами в области, отображение контекста и т. Д. Это должно быть движущей силой дизайна приложений высокого уровня.
Оба являются поверхностными объяснениями двух мощных методологий программирования. Но в конце концов они действительно выполняют две совершенно разные вещи.
Начните с языка DDD и сопоставления контекста, а затем, когда вы начнете писать код, начните практику TDD. Но практика TDD не должна влиять на дизайн высокого уровня, но она должна гарантировать, что что-то может быть проверено. Здесь есть небольшая оговорка.
Я думаю, что это может быть важно отметить: вы должны практиковать DDD, только если приложение достаточно сложное.
источник
DDD о разработке программного обеспечения.
TDD о дизайне кода.
В DDD «модель» представляет собой абстракцию домена, все знания от эксперта области.
Мы могли бы использовать TDD для исходной модели программного кода. Домен имеет бизнес-правила и доменные модели, которые написанные тесты (первые) должны быть зелеными.
По сути, мы можем кодировать тесты после разработки модели, управляемой доменом.
Эта книга "Растущее объектно-ориентированное программное обеспечение, ориентированное на тесты". Ссылка для покупки.
Используйте этот подход с ходячим скелетом , гексагональной архитектурой и TDD.
Источник: DDD быстро - InfoQ
источник
Нет. (Управляемый доменом) Дизайн по определению должен исходить из требований домена. Это плохая идея, чтобы позволить чему-то другому управлять вашим дизайном, будь то набор тестов, схема базы данных или ... (продолжение следует)
(продолжение) ... или какие-то канонические слои классов / иерархий классов на вашем любимом ОО-языке, даже если он очень зрелый и популярный (в конце концов "миллионы мух не могут ошибаться", верно?) ,
Когда дело доходит до DDD, ООП не отвечает требованиям, выражая их в удобочитаемой форме, то есть что-то, что было бы более или менее понятно для непрограммиста. Строго типизированные языки FP делают лучше. Я рекомендую прочитать книгу о DDD, используя функциональное программирование Скотта Влашина «Моделирование предметной области сделано функциональным»
https://pragprog.com/book/swdddf/domain-modeling-made-functional
Вам не нужно использовать язык FP, чтобы позаимствовать некоторые идеи оттуда (не все из них, к сожалению, к сожалению), но если вы действительно прочитаете его, то, возможно, вам захочется использовать функциональный язык.
Он также ответит на ваш вопрос о том, как TDD вписывается в изображение DDD. Вкратце, когда требования кодируются в функциональном стиле, это устраняет необходимость в большом количестве модульных тестов, поскольку делает большинство недопустимых состояний и сценариев непредставимыми / невозможными для компиляции. Конечно, в проекте FP все еще есть место для автоматизированного тестирования, но тесты ни в коем случае не будут определять какие-либо важные проектные решения.
Чтобы сделать полный круг, давайте вернемся к заглавному вопросу, т.е. «Как объединить строгий TDD и DDD?». Ответ прост: нечего объединять / нет конфликта интересов. Проектируйте в соответствии с требованиями, разрабатывайте в соответствии с дизайном (сначала пишите тесты, если вы действительно хотите сделать TDD)
источник