Comments 13
Понравилось, это что нужно обсуждать. А то ситуация из разряда: ДДД - это тру, анемичная модель - антипаттерн и, вообще, сама получается, значит обсуждать её не нужно.
Я в своих проектах АПИ использую похожие подходы, но напишу про важное для меня:
Если логики нет или она простая - тестирую через интеграционные тесты. Например, проверяю успешный кейс и то, что можно не пройти валидацию. Все ветви юскейса.
Если в юскейсе есть немного логики, но выносить её в отдельный файл кажется перебором, то делаю её просто статическим методом. Да, публичный статический метод, который нужен только для тестирования. Но т.к. юскейсы вызываются только из конечных точек, то он там никому не мешает.
Все компоненты в DI - статические. Т.е. вся логика не имеет состояния кроме БД.
Если алгоритм проще реализовать через объект с данными, то создаю через фабрику из DI, либо вообще через new по месту использования.
Сервисы с логикой стараюсь делать специализированными, чтобы не было OrderService на 5к строк.
В юнитах почти никогда ничего не мокаю, т.к. чистые функции.
Использую async/await, что является прекрасным маркером есть там ввод/вывод или нет.
сама модель у нас имеет только поля, геттеры и сеттеры, при этом вся бизнес-логика пишется практически всегда в сервисах
Отсутствие общих правил, для каждого сервиса свои правила (часто вместе с отсутствием общих типов), обработка сильно связана с контекстом (значит и тесты зависит от контекста - им нужно передать данные из БД, файла, внешнего ввода).
Ммм. Кушайте, не обляпайтесь.
Другое дело, что под богатой моделью не стоит понимать обязательно ООП. Богатая модель прекрасно живёт на ФП и событиях. +10% к стоимости разработки и -30% к стоимости сопровождения.
неиспользование силы ООП
Можно подробней? Из ссылки не ясно
Фаулер не умеет ничего кроме ООП, не читайте его
Другое дело, что под богатой моделью не стоит понимать обязательно ООП. Богатая модель прекрасно живёт на ФП и событиях.
DDD (стратегические паттерны) так точно не обязательно применимо только к ООП. А вот насчёт богатой модели — не уверен. Если говорить про ФП — там одна из главных идей в чистых функциях. Сложно представить, как богатую модель совместить с чистыми функциями. У меня давно в списке для чтения лежит книжка про функциональное DDD — я её пару раз пролистывал, но ничего про богатую модель не видел. Поэтому буду рад если вы сможете привести примеры.
Можно подробней? Из ссылки не ясно
Ну, если вспомнить определение объекта в ООП — это смешение данных и поведения. В анемичной модели мы теряем и это, и инкапсуляцию на уровне объекта. Вот ссылка с привязкой к абзацу
Если верить краткому переводу, то в первой части ссылка на луковичную архитектуру, где домен отдельно от сервисов.
Прямого указания нет. Но она сильно подталкивает к богатой модели.
Смысл "лука" — изолировать логику домена в центре.
Богатая модель помещает логику внутрь сущностей (order.Complete()). Это идеально ложится в ядро "лука".
Анемичная модель выносит логику в сервисы (OrderService.Complete(order)). Ядро превращается в набор DTO и сервисов
С другой стороны, богатую модель принято связывать с ООП (защита инвариантов объектов). Может быть, поэтому автор и не употреблял терминов богатая или анемичная модель.
Вообще, очень жаль, что все термины буквально засраны следами ООП.
Вот ссылка с привязкой к абзацу
Не читайте. Устарело на 20+ лет
Опять же защита инвариантов в ФП прекрасно делается через систему типов, даже лучше чем в ООП.
Вместо одного изменяемого объекта используется набор неизменяемых типов, каждый из которых представляет определённое состояние.
UnpaidOrder, PaidOrder, ShippedOrder
Весь жизненный цикл заказа — это функция-воркфлоу, которая трансформирует один тип в другой:
pay(order: UnpaidOrder) -> PaidOrder
ship(order: PaidOrder) -> ShippedOrder
Нельзя вызвать ship для UnpaidOrder — код просто не скомпилируется. Идентичность (Id) просто копируется из одного состояния в другое.
А вот это интересно. Выглядит как реально хороший способ защиты инвариантов. Хотя я так понимаю что с усложнением бизнес логики там будут свои минусы - огромное количество типов в разных состояниях, сложность работы с разными типами одновременно, сериализация/десериализация и тд.
Ну, луковичная архитектура — это что-то более высокоуровневое, без привязки к ООП или ФП. В моём понимании неважно, как будет реализовано ядро — чистыми функциями или богатой доменной моделью(объектами с данными и поведением), главное, чтобы доменная логика была отделена от других слоёв.
Богатая модель помещает логику внутрь сущностей (order.Complete()). Это идеально ложится в ядро "лука".
Ну вот именно поэтому я не вижу, как она может быть реализована в ФП без костылей и нарушений правил ФП. Поэтому придерживаюсь термина "Доменная модель", если говорю просто о какой-то абстрактной модели. А дальше она может быть Богатой, Анемичной, Функциональной и т.д. Хотя, конечно, у тех же ООП-приверженцев зачастую просто "Доменная Модель" = "Богатая Доменная Модель", с чем я уже не согласен.
С другой стороны, богатую модель принято связывать с ООП (защита инвариантов объектов). Может быть, поэтому автор и не употреблял терминов богатая или анемичная модель.
Вообще, очень жаль, что все термины буквально засраны следами ООП.
Ну так это неспроста. Эванс и Фаулер были, даже если не изобретателями большинства терминов, то как минимум их популяризаторами. Да и если смотреть на процент распространения ООП и ФП-языков и архитектур/подходов, то первых несравненно больше. Будь ФП сейчас таким же популярным, то как вы говорите всё было бы "засрано" следами ФП.
Не читайте. Устарело на 20+ лет
А как по вашему ООП или DDD изменились за 20+ лет? :)
ООП или DDD изменились за 20+ лет?
Вырос интерес к ФП из-за более простой реализации параллельного программирования. Как следствие, мейнстрим языки получили ФП инструменты: C#, Java. Появились ФП ориентированные языки компаньоны F#, Scala, Kotlin.
Согласен, но это ведь не концептуальное изменение парадигм. Это просто завезённые инструменты или смешение подходов. То, что я на той же Джаве могу использовать стримы или лямбды, не меняет принципов ООП — скорее делает Джаву более мульти-парадигмальным языком. И в целом, я считаю что это прекрасно — вместо того чтобы уходить в крайности и проповедовать чистое ООП или ФП, почему бы не брать лучшее из обоих миров.
Да и если смотреть на процент распространения ООП и ФП-языков и архитектур/подходов, то первых несравненно больше
По объему ФП 10-20%, но без него плохо.
Функциональное ядро, императивная оболочка. В ядре общие правила, их не так и много, они краткие, но ответственные. В оболочке конкретные случаи, вызывающие / дирижируюшие остальное
Прочитал
Вы предлагаете модель функциональное ядро, императивная оболочка. Плюс мысли о том, что ядро домена разделить на мини ядра.
Ну ок. Подход рабочий. Вы отучаетесь от ООП, поздравляю.
Преодоление сложности в самом сердце Анемичной Модели