Что такое ddd в программировании

Domain-Driven Design: стратегическое проектирование. Часть 1

Здравствуйте, хабрапользователи! В этой статье речь пойдет о предметно-ориентированном проектировании программного обеспечения с использованием, в первую очередь, стратегических шаблонов. Вторую часть – про тактическое проектирование – читайте здесь.

Данный подход использовал Вон Вернон в своей книге «Реализация методов предметно-ориентированного проектирования». Цель написания этой книги: дать возможность разработчикам совершить полет на самолете DDD (в детстве автор зачастую путешествовал со своей семьей на небольших самолетах). Вид с высоты дает более широкое представление о проблемах моделирования, не давая застрять в различных технических деталях. Наблюдая ландшафт DDD таким способом, можно осознать преимущества как стратегического, так и технического проектирования. Подробнее – под катом!

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

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

Единый язык

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

Приведу несколько примеров из книги:

В команде, обсуждая модель применения вакцины от гриппа в виде кода, произносят фразу наподобие: «Медсестры назначают вакцины от гриппа в стандартных дозах». Возможные варианты развития событий:

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

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

Ограниченный контекст

Эта концептуальная граница называется ограниченный контекст (Bounded context). Это второе по значимости свойство DDD после единого языка. Оба эти понятия взаимосвязаны и не могут существовать друг без друга.

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

Контекст банковских услуг

Сводка поддерживает запись о дебиторских и кредиторских транзакциях, отображающих текущее финансовое состояние клиента с точки зрения банка → Сводка о текущих счетах или сводка о сберегательных счетах

Сводка – это совокупность литературных выражений об одном или нескольких событиях, произошедших за определенный период времени → На сайте amazon.com продается книга Into Thin Air: A Personal Account of the Mt. Everest Disaster

Предметная область, предметная подобласть, смысловое ядро

Это и есть основа для стратегического проектирования при подходе DDD.

Пространство задач и пространство решений

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

Итак, для оценки пространства задач в первую очередь необходимо:

Карта контекстов

Естественный ход событий – совпадение границ контекстов с организационным делением команды. Люди, работающие вместе, разделяют один общий контекст модели.

Существуют такие отношения между ограниченными контекстами и отдельными командами проекта:

Сначала рисуется простая карта контекстов с границами и связью между ограниченными контекстами :

Например, PayeeAccount – это тот же BankingAccount, но с другим поведением (нельзя получить баланс). Таким образом будет создан отдельный контекст учета расходов (expense tracking). Также отдельно, в приведенном примере, создается контекст онлайн сервисов банка (on-line banking services) (такие сервисы, например, как распечатка выписок банка).

Детализированная карта выглядит вот так:

Так как контекст профайлов веб-пользователей используется как готовый внешний модуль и он поставляется «как есть», здесь устанавливается отношение конформист (нижестоящий подчиняется вышестоящему).

Вывод

Спасибо за внимание!

Статью подготовили: greebn9k (Сергей Грибняк), wa1one (Владимир Ковальчук), silmarilion (Андрей Хахарев).

Источник

DDD также обеспечивает основу для стратегического и тактического моделирования. Стратегическое проектирование позволяет точно определить наиболее важные области разработки на основе бизнес-ценностей. Тактическое моделирование нужно для построения работающей Доменной Модели с использование проверенных в бою строительных блоков и шаблонов.

Три столпа DDD

Domain-Driven Design это подход к разработке программного обеспечения, который сфокусирован на трёх основных принципах:

Единый язык (Ubiquitous Language)

Итак, как найти, изучить и запечатлеть этот особый язык, следующие подсказки помогут вам в этом:

Определение DDD

DDD это не серебряная пуля; как и все в программном обеспечении, всё зависит от контекста. Старайтесь использовать этот подход чтобы упростить ваш Домен (Domain), а не добавляйте сложности. Если разрабатываемое вами приложение ориентировано на работу с данными и ваши сценарии в основном подразумевают CRUD операции (создание, чтение, обновление, удаление), то вам не нужен DDD. Вам всего лишь нужен интерфейс манипуляцией данными в вашей хранилище.

Если в вашем приложении реализует менее 30 сценариев использования (Use Cases), может вам проще использовать фреймворки Symfony или Laravel, для управления всей бизнес логикой.

Однако, если ваше приложение имеет более 30 сценариев использования, ваша система подвержена движению в сторону Большого Комка Грязи (Big Ball of Mud). Если вы точно знаете что ваша система будет достаточно сложной, то вам следует рассмотреть возможность использования DDD для борьбы с этой сложностью.

Если вы знаете, что ваше приложение будет расти и, вероятно, часто изменяться, то DDD определенно поможет вам в контроле сложности и реализации рефакторинга вашей модели с течением времени.

Если вам не понятен домен (Domain), над которым вы работаете, потому что он новый и никто ранее не вкладывал средства в это решение, это может означать, что он достаточно сложен для того чтобы с ходу начать применять DDD. В этом случае вам стоит в первую очередь начать тесное взаимодействии с экспертами предметной области (Domain Experts) для построения правильной модели.

Некоторые нюансы

Применять DDD не просто. Необходимо время и усилия, чтобы построить бизнес-домен, создать терминологию, провести исследования и организовать сотрудничество с экспертами предметной области используя единый язык, без профессиональных терминов программистов.

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

Вдобавок ко всему, вам придется приложить усилия, чтобы избежать технических моментов реализации на начальном этапе, а сосредоточиться в первую очередь о поведении объектов и создании единого языка (Ubiquitous Language).

Стратегический обзор

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

Если вы хотите узнать больше о стратегической части DDD, вам следует взглянуть на первые три главы книги Вона Вернона «Реализация методов предметно-ориентированного проектирования» или книгу Эрика Эвинса «Предметно-ориентированное проектирование (DDD). Структуризация сложных программных систем»

Выводы

Реализация DDD требует усилий. Если бы это было легко, все писали бы качественный код. Будьте готовы, потому что вы скоро узнаете, как писать код, который при прочтении отлично описывает бизнес вашей компании.

Источник

TDDx2, BDD, DDD, FDD, MDD и PDD, или все, что вы хотите узнать о Driven Development

Просматривая статьи по проектированию ПО, я постоянно встречал тучу невиданных сокращений и вскользь упоминаемых практик разработки.

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

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

TDD — Test Driven Development

TDD — это методология разработки ПО, которая основывается на повторении коротких циклов разработки: изначально пишется тест, покрывающий желаемое изменение, затем пишется программный код, который реализует желаемое поведение системы и позволит пройти написанный тест. Затем проводится рефакторинг написанного кода с постоянной проверкой прохождения тестов.

Звучит просто и понятно. Многим знаком такой подход к разработке и даже сам “Uncle Bob” активно его пропагандирует.

TDD считается одной из форм правильного метода построения приложения. Философия разработки на основе тестов заключается в том, что ваши тесты являются спецификацией того, как ваша программа должна вести себя. Если вы рассматриваете свой набор тестов как обязательную часть процесса сборки, если ваши тесты не проходят, программа не собирается, потому что она неверна. Конечно, ограничение заключается в том, что правильность вашей программы определена только как полнота ваших тестов. Тем не менее, исследования показали, что разработка, основанная на тестировании, может привести к снижению ошибок на 40–80% в производстве.

Начав использовать TDD, вы можете почувствовать, что работаете медленнее, чем обычно. Так происходит потому что вы будете работать вне «зоны комфорта», и это вполне нормально.

После того, как вы ощутите, что написание тестов стало простой и естественной частью рабочего процесса, что вам больше не нужно думать об использовании TDD при работе над проектом, вы осознаете, что TDD влилось в вашу работу.

Эта методология позволяет добиться создания пригодного для автоматического тестирования приложения и очень хорошего покрытия кода тестами, так как ТЗ переводится на язык автоматических тестов, то есть всё, что программа должна делать, проверяется. Также TDD часто упрощает программную реализацию: исключается избыточность реализации — если компонент проходит тест, то он считается готовым.

Архитектура программных продуктов, разрабатываемых таким образом, обычно лучше (в приложениях, которые пригодны для автоматического тестирования, обычно очень хорошо распределяется ответственность между компонентами, а выполняемые сложные процедуры декомпозированы на множество простых). Стабильность работы приложения, разработанного через тестирование, выше за счёт того, что все основные функциональные возможности программы покрыты тестами и их работоспособность постоянно проверяется. Сопровождаемость проектов, где тестируется всё или практически всё, очень высока — разработчики могут не бояться вносить изменения в код, если что-то пойдёт не так, то об этом сообщат результаты автоматического тестирования.

Подробнее с принципами TDD вы можете ознакомиться, прочитав книгу Кента Бека “Экстремальное программирование. Разработка через тестирование”.

TDD — Type Driven Development

Type Driven Development сокращенно пишется также, как и разработка через тестирование, поэтому обычно пишут полное название.

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

Типы представляют из себя небольшие контрольные точки, благодаря которым, мы получаем множество мини-тестов по всему нашему приложению. Причем затраты на создание типов минимальны и актуализировать их не требуется, так как они являются частью кодовой базы.

Разработка по типу — это еще один правильный метод построения приложения. Как и в случае разработки на основе тестирования, разработка на основе типов может повысить вашу уверенность в коде и сэкономить ваше время при внесении изменений в большую кодовую базу.

Из минусов только возрастающая сложность у языков с динамической типизацией. К примеру, для JavaScript этот подход тяжелее применить, чем для TypeScript.

BDD — Behaviour Driven Development

Из-за некоторого методологического сходства TDD (Test Driven Development) и BDD (Behaviour Driven Development) часто путают даже профессионалы. В чем же отличие? Концепции обоих подходов похожи, сначала идут тесты и только потом начинается разработка, но предназначение у них совершенно разное. TDD — это больше о программировании и тестировании на уровне технической реализации продукта, когда тесты создают сами разработчики. BDD предполагает описание тестировщиком или аналитиком пользовательских сценариев на естественном языке — если можно так выразиться, на языке бизнеса.

BDD — behaviour-driven development — это разработка, основанная на описании поведения. Определенный человек(или люди) пишет описания вида “я как пользователь хочу когда нажали кнопку пуск тогда показывалось меню как на картинке” (там есть специально выделенные ключевые слова). Программисты давно написали специальные тулы, которые подобные описания переводят в тесты (иногда совсем прозрачно для программиста). А дальше классическая разработка с тестами.

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

Тексты сценариев записываются в определенной форме.

Имея (прим. given — данное) какой-то контекст,

Когда (прим. when) происходит событие,

Тогда (прим. then) проверить результат.

Источник

Проектируем по DDD. Часть 1: Domain & Application

xxx: пока скачаешь одну библиотеку, пока другую, пока их xml конфигом на полметра склеишь, пока маппинг для hibernate настроишь, пока базу нарисуешь, пока веб-сервисы поднимешь
xxx: вроде и hello world пишешь, а уже две недели прошло и всем кажется, что это учетная система для малого бизнеса
ibash.org.ru

В серии из нескольких статей я хотел бы на простом, но имеющим некоторые нюансы, примере рассказать о том, как имея готовые domain и application слои реализовать под них инфраструктуру для хранения и извлечения данных (infrastructure for persistence) используя две различные популярные технологии – Entity Framework Code First и Fluent NHibernate. Если вы хотя бы слышали про три буквы DDD и у вас нет желания послать меня на тоже три, но другие буквы — прошу под кат.

Собственно, само название DDD (Domain-driven development) говорит о том, что разработка начинается и «ведется» предметной областью, а не инфраструктурой и чем-либо ещё. В идеальной ситуации при проектировании вы не должны задумываться о том, какой фрэймворк для хранения данных будет использоваться и как-то менять домен под его возможности – так поступим и мы: в первой статье я опишу пример, под который собственно мы и будем реализовывать инфраструктуру.

Domain Layer

Источник

Domain-Driven Design: тактическое проектирование. Часть 2

Сущность (Entity)

Есть несколько стратегий создания идентификаторов:

Ввод пользователем уникального значения

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

Идентификатор генерируется приложением

Идентификатор генерируется механизмом постоянного хранения

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

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

Идентификаторы, которые присваиваются другими ограниченными контекстами

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

Объект-Значение (Value Object)

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

Рассмотрим классический пример объекта значения денежная сумма (во многих примерах в интернете встречается этот класс):

Давайте перейдем к следующему важному шаблону тактического моделирования.

Служба Предметной Области (Domain Service)

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

Событие (Domain Event)

Изучая предметную область, встречаются факты, которые имеют особую важность для экспертов в предметной области. Например от экспертов можно услышать такие ключевые фразы:

Для примера можно рассмотреть событие FundsDeposited:

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

Существует много компонентов для передачи сообщений, которые относятся к классу промежуточного программного обеспечения (например, RabbitMQ, NServiceBus). Можно также сделать обмен сообщениями с помощью ресурсов REST, где автономные системы обращаются к издательской системе, требуя уведомления о событиях, которые еще не были обработаны.

Подход RESTful к публикации уведомлений о событии является противоположностью публикации с помощью типичной инфраструктуры обмена сообщениями. «Издатель» не поддерживает ряд зарегистрированных «подписчиков», потому что заинтересованным сторонам ничего не рассылается. Вместо этого подход требует, чтобы клиенты REST сами запрашивали уведомления, используя ресурс URI.

В обоих случаях – когда подписчики используют промежуточное программное обеспечение для обмена сообщениями, или когда клиенты уведомлений используют REST – важно, чтобы отслеживание идентификационных данных обработанных сообщений фиксировались вместе с любыми изменениями в локальном состоянии модели предметной области.

Давайте рассмотрим следующий шаблон DDD.

Модуль (Module)

Есть определенные правила именования модулей. Имена модулей (во многих языках программирования) отображают их иерархическую форму организации. Иерархия имен обычно начинается с доменного имени организации, которая разрабатывает модуль (чтобы избежать конфликтов). Например:

Далее следует квалификатор, который идентифицирует модуль именно предметной области:

Все модули модели можно поместить именно в этом разделе domain. Вот так:

В известной всем многоуровневой архитектуре именование было бы таким:

сom.bankingsystems.resources
сom.bankingsystems.resources.view – уровень пользовательского интерфейса (хранение представлений)

сom.bankingsystems.application
сom.bankingsystems.application.account – прикладной уровень (подмодуль прикладных сервисов )

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

Агрегат (Aggregate)

У каждого агрегата есть корень (Aggregate Root) и граница, внутри которой всегда должны быть удовлетворены инварианты.

Инвариант – это бизнес-правило, которое всегда сохраняет свою непротиворечивость. Это явление называется транзакционной согласованностью, которая является атомарной. Есть еще и итоговая согласованность. В случае инвариантов, речь идет о транзакционной согласованности. Агрегатом также можно называть границу транзакционной согласованности, внутри которой выполняются инвариантные правила, независимо от того, какие именно операции при этом выполняются.

В качестве примера агрегата можно привести кредитный отчет:

При удалении агрегата отчета, должны удаляться все значения – записи об истории и запросах.

Фабрика (Factory)

Шаблон фабрика является более известным, чем другие.

Некоторые агрегаты или сущности могут быть достаточно сложными. Сложный объект не может создавать сам себя посредством конструктора. (В книге Эрика Эванса был приведен пример: двигатель автомобиля, который собирается либо механиком, либо роботом, но он никак не должен собираться сам по себе.) Еще хуже, когда передают создание сложного объекта на клиент. Так, клиент должен знать о внутренней структуре и взаимосвязях внутри объекта. Это нарушает инкапсуляцию и привязывает клиента к определенной реализации (таким образом, при изменении объекта придется менять и реализацию клиента).

Объекты-значения и сущности создаются по-разному: так как значения неизменяемы, все атрибуты должны передаваться сразу при создании. А в сущность можно добавлять только те, которые важны для создания конкретного агрегата и его инвариантов.

Хранилища (Repository)

Есть два типа проектов хранилищ :

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

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

Реализация хранилища использует методы и объекты механизма. При это реализация находится на инфраструктурном уровне, а интерфейс объявляется в домене.

Вывод

Надеемся, что статья помогла вам продвинуться в понимании шаблонов DDD! Если есть вопросы, пишите в комментариях. С радостью ответим. И спасибо за внимание.

Статью подготовили: greebn9k (Сергей Грибняк), wa1one (Владимир Ковальчук), silmarilion (Андрей Хахарев).

Источник

Понравилась статья? Поделиться с друзьями:

Не пропустите наши новые статьи:

  • Что такое daw программа
  • Что такое data science в программировании
  • Что такое daemon в контексте linux
  • Что такое daemon в linux
  • что такое d3dx9 43 dll для windows 7

  • Операционные системы и программное обеспечение
    0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest
    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии