Комментарии 64
Что такое DDD, можно объяснить даже ребёнку (или маркетологу)Маркетологу объяснить это как раз не сложно. Гораздо сложнее объяснить что это такое программисту.
Но сам по себе DDD не исключает архитекторов и аналитиков (как и дизайнеров с тестировщиками). Но не снимает с разработчика почетной обязанности погружаться в домен и бизнес.
Именно. Программист, осознанно работающий по DDD, должен обладать навыками аналитика. Хотя бы чтобы заметить, что новые желания плохо согласуются с имеющимися моделями и их надо изменять, а не тупо добавить пару свойств и с десяток if'ов.
С другой стороны, бизнес-аналитик может быть единственным экспертом предметной области, доступный программистам, и это тоже будет DDD. Детали реализации, как говорится.
мидл и ниже, уже настолько у них низкое воздействие на результатТак приближение к бизнесу подразумевает повышение воздействия.
пожинать плоды будет уже кто-то другойВы акционер или совладелец бизнеса? Я говорю про обычных программистов на зарплате.
усилия на нерелевантные знанияЧтобы продавать себя дороже. Не так уж много знаний и так или иначе придётся в них вникать (программирование — перевод из человеческого на формальный язык), а эффект намного больше, чем от изучения очередного фреймворка (который скорее всего не пригодится). Ну и в любом случае переводить из языка бизнеса в формальный кому-то нужно. Пусть при ваших процессах идея DDD будет тогда не для вас, а для ваших сеньоров, например.
лично тебе это фактически не приносит прибылиЛюбой положительный эффект для бизнеса — это растущая ценность и для специалиста. Именно за это бизнес платит деньги людям.
вы за мир во всём мире, примерно похоже по глубине и информативностиЯ за мир в своём кармане и говорю о том, что меня спрашивают на собеседованиях и чем я стараюсь себя продать. The Best Code is No Code At All, без привычки вникать в бизнес-процессы можно только по чьей-то указке послушно закрывать разжеванные тикеты, надеясь на то, что все требования уже формализованы и написаны. Но это не особо ценится. Разработчик > кодер.
Так и есть, при устройстве в IT отдел кондитеской фабрике у вас в резюме будет «в деталях овладел техпроцессом производства синтетической резины». Это позволит себя продать дороже.
Примерно так, только другими словами. Например, за 3 месяца погрузившись в детали предметной области (техпроцессом производства синтетической резины), нашёл места легко поддающиеся автоматизации, подготовил MVP для этого, после демонстрации которого отвечал за техническую часть его дальнейшего развития. Внедрение продукта позволило снизить время производства очередной партии на 10%, а фонд оплаты труда на 50.
А где слово "искать" вы увидели? Анализировал насколько модель хорошо описывает реальность, и увидел, что в этой реальности кто-то делает что-то, что легко автоматизировать. Ну, например, распечатывают бумажку, несут ее другом учеловеку, а аон вводит её в другую программу и даже в архив не передает
Что-то мне подсказывает что данная методология направлена в основном на вторую часть.
зачем тратить усилия на нерелевантные знания, которые с достаточно большой вероятностью придётся выбросить на помойку на следующем месте работы
Что-то мне подсказывает, что вы неправильно понимаете, что такое DDD. Оно не о том, чтобы программист делал что-то, что не входит в его обязанности.
разговаривать с бизнесом на одном языке
Грубо говоря, это означает, что если в бизнесе используется термин "клиент", то в коде эту сущность надо называть "Client", а не "User". Если в бизнесе есть некоторый процесс, который имеет устойчивое название, в коде должен быть метод с аналогичным названием и содержанием, а не Button1Click какой-нибудь. От этого уже идет все остальное.
а потому что кто-то, почему то, решил что это будет вот так
Да, и модель должна это отражать. Потому что она модель, она для этого и делается.
Зачем использовать кривые термины если можно выпрямить.
Затем, что если бизнес их использовать не будет, то будет непонятно, что вообще надо менять при изменении требований. Бизнес скажет, надо печатать на билете в кино ограничение по возрасту, а у вас в коде Button1Click, Button2Click, Button3Click. Какой метод будете менять? Код всех 3 изучать? А зачем, если можно сразу нормально назвать?
Вообще, определение того, кривые у бизнеса термины или нет, это уж точно не обязанность программиста.
Пусть отражает, завтра придёт новый Вася и ему придётся новые термины изучать.
Какие новые термины? Термины всегда одни и те же, те, которые используются в бизнесе, в том и смысл.
У меня вопрос про то как программист учит эти бизнес термины. Ему глоссарий/толковый словарь выдают или он реально должен этот бизнес учить?
Очень просто — не придумывает свои. Вот как раз если он будет свои придумывать, то будет нужен словарь, какой термин бизнеса какому названию в коде соответствует. Не знаю, почему вы решили, что он должен что-то учить. Термины вон они, в задачах и обсуждениях, зачем их учить.
Глоссарий единого языка — один из артефактов DDD. А "учит" не совсем подходящее слово. Изучает в мере необходимой, чтобы создать модель бизнеса и представить её в коде.
А если один бизнес человек говорит client а другой user?
Тут надо разобраться и заставить либо использовать один термин, если реально говорят об одном и том же в одном контексте, либо понять, что одна сущность реального мира может выступать в разных контекстах и как клиент, и как пользователь. Ну и выделить эти контексты в модели и коде и договориться где пользователь, а где клиент.
невнятно проблеять может кто угодно на любой стадии
Во-первых, DDD не ограничивает источники единого языка, он просто должен быть единым в рамках чётко определённого контекста. И бизнес вполне может перестать использовать некоторые "доморощенные" термины в пользу предложенных разработчиками. И это реально работает.
DDD роли бизнес-аналитика и архитектора не исключает. Более того, субъективно, их функции становятся более важными. Бизнес-аналитик же по определению должен быть экспертом предметной области. Или нет? Да и архитектуру кто-то должен определять. Например, "достоин" ли какой-то контекст, агрегат или даже сущность выноса в отдельный сервис или нет.
В пределе, наверное, бизнес-аналитик и архитектор могут "заставить" разработку идти по DDD даже без ведома разработчиков. Архитектор определит слои, бизнес-аналитик контексты и модели, а разработчики будут это имплементировать. Разве что жаловаться будут на то, что эти самодуры лезут в детали реализации, типа какая разница как у нас класс называется, если пользователь этого не знает. Или что запрещают инжектить сервис в сущность через конструктор, хотя это удобно.
запрещают инжектить сервис в сущность через конструкторВот это мне не удаётся хорошо обосновать. Стараюсь через Clean Architecture, но с сомнительным успехом. Еще через глобальное состояние и «чистоту» эффектов, но через это по-видимому я вообще только себе могу что-то доказать. В материалах по DDD разве есть что-то про это? По-моему нет.
Точно не помню, есть ли дословно, но слой доменной логики, где и лежат сущности не должен зависеть от других слоёв, что исключает зависимость от инфраструктурных и т. п. сервисов. То есть инжектить какой-нибудь инфраструктурный эмиттер событий нельзя, потому что это будет зависимостью от инфраструктурного слоя.
Остаются бизнес-сервисы, сервисы предметной области. Тут подход другой: мы моделируем сущность, она имеет жизненный цикл и создаётся, конструируется только один раз. То есть ее конструктор должен вызываться только один раз. Если про rest-like веб API говорить, то где-то в обработчике соответствующего POST метода. Если про UI, то где-то в обработчик кнопок new/create/etc.
Используемый ORM/ODM/… или даже язык в целом, может не допускать такой сценарий и придётся использовать какой-то именованный конструктор/фабричный метод/фабрику, но вот семантика должна сохраниться, то есть инжектить сервисы через конструктор даже под их капотом всё равно нельзя, по-моему. У класса сущности должна быть одна ответственность — моделировать сущность предметной области. Если и надо что-то инжектить в сущность, то из-за эфемерной природы программных сервисов (их в базу не сохранишь), то через double dispatch
Если и надо что-то инжектить в сущность, то из-за эфемерной природы программных сервисов (их в базу не сохранишь), то через double dispatchТо есть инжектить сторонние зависимости через сигнатуру метода сущности? Тогда остаётся вопрос, в какой момент остановиться и не отработать весь процесс приложения в этом методе сущности)
Тут подход другой: мы моделируем сущность, она имеет жизненный цикл и создаётся, конструируется только один раз. То есть ее конструктор должен вызываться только один раз.
Я уже где-то встречал это мнение, кажется в сообществе Doctrine так считается. Я думаю, это неправильный подход. Конструктор это по своей природе функция, которая вызывается при создании объекта в оперативной памяти некоторого процесса, для инициализации занимаемой им оперативной памяти. Это инфраструктурная вещь. Если у нас есть более высокоуровневая абстракция, если у нас одна и та же сущность может появляться в разных процессах, значит и для конструктора нужно создать более высокоуровневую абстракцию, специальный бизнес-конструктор, который и будет вызываться один раз. А не пытаться через рефлексию и аннотации имитировать то, что должно быть в конструкторе.
Я исхожу из того, что код домена, написанный по DDD должен быть в целом понятен бизнесу (англоговорящему). И где-то в коде new Customer($name, $address)
будет более понятно при таком подходе, чем CustomerFactory::create($name, $address)
. Хотя в принципе непринципиально. Можно и фабричным методом/классом, особенно в форме Customer::registerNewCustomer(($name, $address)
. Но вот программные зависимости, а не значения свойств сущности в конструкторе класса сущности, по-моему, зло, которого не должно быть независимо от того Doctrine это или нет. Для меня это говорит о плохой проработке модели, или о выборе непоходящего для DDD инструментария, типа использования в качестве сущности наследника какого-нибудь ACtiveRecord
Убедиться, что этот подход поможет в конкретном случае.Но как это можно сделать не попробовав?
Изучить какие проблемы подход решает, какие приносит, и стоит ли овчинка выделки в конкретном случае. Может стоит применять его только частично или в ограниченной области системы. Например в конкретном случае вполне может оказаться, что нет смысла тащить DDD на фронт или, наоборот, на бэк. Или на БД может оказаться слишком дорого менять схему данных на каждый чих в UI
У Эванса нет бороды. У Вернона тоже.
Интересно, как воспринимают мир программисты, которые сразу начали через DDD осваивать эту стязю?
Но, как известно
Talk is cheap. Show me the code.
Покажите ваши классы Price и Money!
А money, деньги, те что обычно число и валюта? Есть такой? Да и price я видел(давно правда, около 3х лет назад), и состоял он в очень странных отношениях с money. И price уже как раз entity, обычно, т.к. привязан к продукту.
Интересно, потому-что я обычно представлял прайс в виде VO.
Или это у вас специфика модели?
в моём понимании для торговли, вполне можно использовать следующий подход:
Money — классический ValueObject, состоящий, в простейшем случае, из количества денег (например Decimal) и валюты.
Price — Цена, цена относится к какому то товару или услуге, она может содержать в себе то, что платит покупатель (деньги — VO), ставку/сумму налогов. Выходит, что нельзя делать её в виде ValueObject при таком подходе — по той причине, что её нужно сравнивать по ссылке, а не по содержанию.
10 рублей как деньги (VO) — они везде 10 рублей и их можно «заменить одни другими»
10 рублей как цена — может содержать разные налоги, и заменять их уже нельзя.
Мне кажется, у вас просто предметная область недостаточно формализована. Если цена содержит в себе сумму налогов, то включите её в цену — и можно будет сравнивать по значению.
Ну так разные налоги — разное содержание и вполне можно сравнивать по содержанию. Идентификатор у цены есть? Цены у двух продуктов "10 рублей, включая 2 рубля НДС" одинаковые? Если изменить у одного, должна ли меняться у другого?
Идентификатор у цены есть?
В моём понимании — нет, цена полностью определяется своим содержимым.
Цены у двух продуктов "10 рублей, включая 2 рубля НДС" одинаковые?
Да.
Если изменить у одного, должна ли меняться у другого?
Нет, конечно. С чего бы?
Само наличие сущности цена, с некоторыми свойствами определяет возможность продажи.
Может быть есть более удачное название для сущности, но я пока не придумал.
Итак «набросок» цены, как один из вариантов сущности:
class Price : Entity
{
public Money Value {get;set;}
public Item Item {get;set;}
public Location Location {get;set;}
public PriceType PriceType {get;set;}
...
}
В данном примере можно задать цену для Товара, с учётом валюты, в разных Локациях (точки продаж, может быть в разных странах) а также типом цены, например для Доставки, Оптовой цены, Особого Клиента или что-то ещё.
При продаже по определённой Цене, в «таблицу проводок» или что-то подобное записывается текущее значение цены.
В таблице проводок используется понятие Денег (ValueObject)
Точно так же как и в Цене, может использоваться в расчётах Прибыли, Расходов, Доходов и т.д.
Тогда ваша цена никкая не сущность, а простой VO, чуть более сложный чем классический Money, но всё равно VO/ Зачем вам сравнение цен по ссылке?
Мне синяя книга показалось гораздо легче для восприятия чем красная (только начал) и зеленая. На мой взгляд, Вон Вернон чересчур сухо и академично пишет. Русскоязычный перевод это еще больше усугубляет.
Если у вас 30-50 и более UX-кейсов
что такое UX-кейс? юскейс? на слух статью писали? )
del. реплай криво отработал.
Что можно узнать о Domain Driven Design за 10 минут?