Я хотел бы знать, что за плюсы и минусы для использования модели анемичного домена (см. ссылку ниже).
Модель анемичной домены: за/против
Ответ 1
Профи:
- Вы можете утверждать, что это модель домена и хвастаться своим друзьям-разработчикам и поместите его в свое резюме.
- Легко создавать автоматически из таблиц базы данных.
- Он отображает объекты передачи данных на удивление хорошо.
Против:
- Ваша логика домена существует где-то иначе, вероятно, в классе, полном класс (статические) методы. Или ваш графический интерфейс код. Или в нескольких местах, все с противоречивой логикой.
- Это анти-шаблон, поэтому другие разработчики спросят, если вы понимать понятия объекта ориентированный дизайн.
Ответ 2
Когда "Модель анемичного домена" является анти-шаблоном, почему существует так много систем, которые реализуют это?
Я думаю, что есть несколько причин
1. Сложность системы
В простой системе (это почти все примеры и примеры кода, которые вы найдете в Интернете), если я хочу реализовать:
Добавление продукта в заказ
Я помещаю эту функцию в Order
public void Order.AddOrderLine(Product product)
{
OrderLines.Add(new OrderLine(product));
}
Приятный и супер объект ориентированный.
Теперь позвольте сказать, что мне нужно убедиться, что мне нужно проверить, что продукт существует в инвентаре и выбрасывает исключение, если это не так.
Я больше не могу его заказать, так как я не хочу, чтобы мой заказ зависел от Inventory, так что теперь ему нужно продолжить службу
public void OrderService.AddOrderLine(Order order, Product product)
{
if (!InventoryService.Has(product)
throw new AddProductException
order.AddOrderLine(product);
}
Я мог бы также передать IInventoryService для Order.AddOrderLine, что является еще одним вариантом, но все еще делает заказ зависимым от InventoryService.
В Order.AddOrderLine по-прежнему есть некоторые функции, но обычно это ограничено областью "Заказ", в то время как в моем опыте намного больше Business Logic выходит из области заказа.
Когда система больше, чем просто базовая CRUD, вы получите большую часть своей логики в OrderService и очень немного в порядке.
2. Взгляд разработчика OOP
В Интернете много горячих дискуссий о том, какая логика должна идти на сущности.
Что-то вроде
Order.Save
Должен ли заказ знать, как сохранить себя или нет? Скажем, у нас есть репозитории для этого.
Теперь можете заказать добавить строки заказа? Если я попытаюсь понять это с помощью простого английского языка, это тоже не имеет смысла. Пользователь добавляет продукт в заказ, так что мы должны делать User.AddOrderLineToOrder()? Это кажется излишним.
Как насчет OrderService.AddOrderLine(). Теперь это имеет смысл!
Мое понимание ООП заключается в том, что для инкапсуляции вы помещаете функции в классы, где функции необходимо будет получить доступ к внутреннему состоянию класса. Если мне нужно получить доступ к коллекции Order.OrderLines, я поставлю Order.AddOrderLine() на заказ. Таким образом, внутреннее состояние класса не подвергается воздействию.
3. Контейнеры IoC
Системы, которые используют контейнеры IoC, обычно полностью анемичны.
Это потому, что вы можете протестировать свои сервисы/репозитории, которые имеют интерфейсы, но не могут протестировать объекты домена (легко), если вы не поместили интерфейсы на всех них.
Так как "IoC" в настоящее время хвалит как решение для всех ваших проблем программирования, многие люди слепо следуют за ним, и этот путь заканчивается с помощью моделей анемичных доменов.
4. ООП сложный, процедурный легко
У меня есть немного "" Проклятие знаний" на этом, но я обнаружил, что для более новых разработчиков, имеющих DTO и Services, намного проще, чем Rich Domain.
Возможно, это связано с тем, что в Rich Domain сложнее узнать, на каких классах поставить логику. Когда создавать новые классы? Какие шаблоны использовать? и т.д..
С помощью служб без состояния вы просто пощекотите его в службе с ближайшим именем.
Ответ 3
Вслед за этим в моей голове появилась очень долгое время. Я считаю, что термин "ООП" принял значение, не предназначенное для него. Анаграмма означает "объектно-ориентированное программирование", как мы все хорошо знаем. Конечно, основное внимание уделяется слову "ориентированный". Это не "OMP", что означает "программирование, предназначенное для объекта". Примерами ООП являются как ADM, так и RDM. Они используют интерфейсы объектов, свойств, методов и т.д. Тем не менее, существует разница между ADM и RDM в том, как мы выбираем кодирование вещей. Это две разные вещи. Сказать, что ADM - плохой ООП, не является точным утверждением. Может быть, нам нужны разные термины для избыточных уровней инкапсуляции. Кроме того, мне никогда не нравился термин анти-шаблон. Обычно это присваивается членам противоположной группы. Оба ADM и RDM являются действующими шаблонами, они просто имеют разные цели и предназначены для решения различных бизнес-задач. Те из нас, кто практикует DDD, должны, по крайней мере, ценить это, а не попадать на уровень других, избивая тех, кто решил внедрить ADM. Просто мои мысли.
Ответ 4
"Это анти-шаблон, поэтому другие разработчики спросят, понимаете ли вы понятия объектно-ориентированного дизайна".
"Анемическая модель домена - это анти-шаблон. У анти-шаблонов нет профи.
Независимо от того, является ли модель анемичного домена анти-паттерном, это вопрос мнения. Мартин Фаулер говорит, что это, некоторые разработчики, которые знают OO наизнанку, говорят, что это не так. Утверждение мнения как факт редко помогает.
An, даже если он был общепризнанным как анти-шаблон, вероятность того, что у него все еще будет некоторый (хотя и относительно небольшой) потенциал роста.
Ответ 5
Мне кажется, что главное возражение Фаулера заключается в том, что ADM не являются OO, в следующем смысле. Если вы разрабатываете систему "с нуля" вокруг пассивных структур данных, которые обрабатываются другими фрагментами кода, то это, безусловно, пахнет скорее как процедурный дизайн, чем объектно-ориентированный дизайн.
Я предполагаю, что есть как минимум две силы, которые могут произвести такой вид дизайна:
-
Дизайнеры/программисты, которые по-прежнему считают, что для работы в объектно-ориентированной среде (или при условии, что они могут...) создать систему new, и
> -
Разработчики, работающие над тем, чтобы поставить "лицо", похожее на службы, на устаревшую систему, разработанную не-OO (независимо от языка).
Если, например, один из них создавал набор сервисов для раскрытия функциональности существующего приложения мэйнфрейма COBOL, можно было бы определить службы и интерфейсы с точки зрения концептуальной модели, которая делает не зеркальным отображением внутренние структуры данных COBOL. Однако, если служба сопоставляет новую модель с устаревшими данными для использования существующей, но скрытой реализации, то новая модель вполне может быть "анемичной" в смысле статьи Фаулера - например, набор определений и отношений в стиле TransferObject без реального поведения.
Такой компромисс может быть очень распространен для границ, на которых идеалистически чистые OO-системы должны взаимодействовать с существующей средой, отличной от OO.
Ответ 6
Модель анемичного домена (ADM) может быть хорошим выбором, если ваша команда неспособна или не желает создавать модель с богатым доменом (RDM) и поддерживает ее с течением времени. Победа с RDM требует пристального внимания к доминирующим абстракциям, используемым в системе. Рисунок, что в любой группе разработчиков не более одной половины и, возможно, только одна десятая ее членов компетентны с абстракциями. Если этот кадр (возможно, только один разработчик) не сможет поддерживать влияние на все групповые действия, RDM будет поддаваться энтропии.
И энтропийный RDM болит, в частности способами. Его разработчики будут изучать суровые уроки. Сначала они смогут оправдать ожидания своих заинтересованных сторон, потому что у них не будет никакой истории, чтобы оправдать ее. Но поскольку их система становится более сложной (не сложной), она станет хрупкой; разработчики будут пытаться повторно использовать код, но склонны вызывать новые ошибки или back-track в разработке (и, таким образом, превышают их оценки).
Напротив, разработчики ADM установят более низкие ожидания для себя, потому что они не ожидают повторного использования кода для новых функций. Со временем у них будет система со многими несоответствиями, но она, вероятно, не будет прерываться неспешно. Их время выхода на рынок будет больше, чем с успешным RDM, но их заинтересованные стороны вряд ли воспримут эту возможность.
Ответ 7
"Разработчики, работающие над тем, чтобы поставить" лицо ", похожее на службы, на устаревшую систему, разработанную не-OO (независимо от языка).
Если вы думаете о многих LOB-приложениях, эти устаревшие системы часто не будут использовать ту же модель домена, что и вы. Анемическая модель домена решает это с использованием бизнес-логики в классах обслуживания. Вы можете поместить весь этот код интерфейса в свою модель (в традиционном смысле OO), но вы, как правило, теряете модульность.
Ответ 8
Когда я впервые встретил статью "Модель анемичной домены", я подумал "святой... ***, что я делаю. ужас!" Я упорствовал и следил за ссылками на книгу Эрика Эвана, которая была хорошим примером и загрузила источник. Оказывается, что "использование немодной модели домена" не означает "не использовать классы обслуживания, а не использовать медиаторы, не используя стратегии" или даже "ставить логику на манипулируемый класс".
В примерах DDD есть классы обслуживания, XyzUpdaters, singleletons и IoC.
Я по-прежнему смущен точно, что такое модель анемического домена. Я ожидаю: "Я это узнаю, когда увижу". На данный момент я доволен положительным примером хорошего дизайна.
Ответ 9
Это то же самое, что и с большинством анти-шаблонов: он позволяет вам долгое время удерживать много людей. Поскольку менеджерам, как правило, платят больше, когда они управляют большим количеством людей, есть сильный стимул не улучшаться.
Ответ 10
В соответствии с ответом Эрика P, а также тем, что написано некоторыми другими выше, кажется, что основным недостатком ADM является потеря OOD, в частности, поддержание логики и данных концепции домена вместе, чтобы детали реализации скрыты, в то время как API может быть богатым.
Эрик продолжает указывать, что часто существует информация вне класса домена, которая необходима для логики действия на этом классе, например, проверка инвентаря перед добавлением элемента в заказ. Я задаюсь вопросом, является ли ответ слоем службы, который содержит эту всеобъемлющую логику, или же он лучше обрабатывается как часть дизайна объекта. Кто-то должен знать об объекте Inventory, объекте Product и объекте Order. Возможно, это просто объект OrderSystem, в котором есть элемент инвентаризации, список ордеров и т.д. Это не будет сильно отличаться от Сервиса, но я думаю, что он концептуально более согласован.
Или посмотрите на это следующим образом: у вас может быть пользователь с внутренним кредитным балансом, и каждый раз, когда пользователь User.addItemToOrder(item) вызывается, он получает цену товара и проверяет кредит перед его добавлением и т.д. Это кажется разумный дизайн ОО. Я не уверен точно, что потеряно, заменив это на Service.addItemToUserOrder(пользователь, элемент), но я не уверен, что получилось. Я предполагаю, что потеря будет лишним слоем кода, а также непринужденным стилем написания и вынужденным незнанием базовой модели домена.
Ответ 11
Работая с "зрелой" системой с ADM и чувствуя, что я могу предоставить некоторую, по крайней мере, анекдотическую обратную связь по этому вопросу.
1) Отсутствие инкапсуляции
В живой системе с ADM существует возможность записи, например. 'obj.x = 100; obj.save ', даже если это нарушает бизнес-логику. Это приводит к ряду ошибок, которые не встречались бы, если бы инварианты были смоделированы на объекте. Это серьезность и распространенность этих ошибок, которые я чувствую, является самым серьезным негативным для ADM.
Я считаю важным отметить здесь, что именно здесь функциональное решение и процедурные решения ADM значительно различаются, и любые сходства, которые другие могли привлечь к сходству поверхности между ADM и функциональным решением, являются случайными.
2) Надувание кода
Я оцениваю, что количество кода, созданного в ADM, составляет 5-10x, что создало бы решение OOP/RDM. Это объясняется, вероятно, 50% повторением кода, 30% - кодовым табличным кодом, а 20% - решением или решением проблем, возникающих из-за отсутствия RDM.
3) Плохое понимание проблем с доменом
ADM и плохое понимание проблем с доменом идут рука об руку. Наивные решения возникают, требования плохо рассматриваются из-за сложности поддержки их с существующим DM, и ADM становится значительным препятствием для бизнес-инноваций, учитывая более длительные времена разработки и отсутствие гибкости.
4) Трудность обслуживания
Требуется определенный уровень строгости для обеспечения того, чтобы концепция домена была изменена во всех местах, где она выражена, учитывая, что концепция может быть не просто повторной реализацией копии и вставки. Это часто приводит к тому, что одни и те же ошибки исследуются и фиксируются несколько раз.
5) Повышенная сложность при посадке
Я думаю, что одним из преимуществ RDM является сплоченность понятий, которые позволяют быстрее понять домен. С концепциями ADM могут быть фрагментированы и не хватает ясности, поэтому для новых разработчиков их сложно усвоить.
Мне также было предложено включить расходы на операционную поддержку для ADM выше, чем для RDM, но это будет зависеть от ряда факторов.
Как отмечали другие, посмотрите на DDD (Грег Эванс, Винс Вон и Скотт Миллетт) на преимущества RDM.
Ответ 12
Чтобы продлить ответ Майкла, я бы подумал (честно) понять, куда должен идти этот код: в специальный посредник, который обрабатывает взаимодействие между Орденом и Инвентарием.
Из моего POV ключевым моментом в домене является то, что он ДОЛЖЕН поддерживать простое поведение тестирования методами isInThisState()
и т.д. По моему опыту они также разбросаны по всей службе слез (sic:)) в большинстве компаний, и либо скопированный бесконечно переписан. Все это нарушает стандартные правила согласования.
На мой взгляд, подход должен заключаться в том, чтобы нацелиться на DM, который удерживает большую часть бизнеса bahavaviour, насколько это практично, остальное в четко обозначенных областях (то есть не в сервисах)
Ответ 13
Моя команда лично предпочитает ADM. у нас есть набор бизнес-объектов, которые представляют собой определенные части нашего домена. Мы используем службы для сохранения этих объектов в db. У наших бизнес-объектов есть методы, однако эти методы управляют им только внутренним состоянием.
Преимущество для использования ADM над RDM можно увидеть в том, как мы сохраняем объекты в db. Разработчики, работающие над нашими устаревшими системами кода, могут использовать наши бизнес-объекты (из новой системы) и продолжать использовать их текущий уровень доступа к данным, чтобы сохранить эти объекты в db. Использование RDM заставит разработчиков нашей унаследованной системы внедрить объекты Репозитория в нашу бизнес-модель... которая не будет соответствовать их текущему уровню доступа к данным.
Ответ 14
Следует отметить, что по мере того, как системы растут по сложности и детализации вариаций, инкапсуляция и консолидация точек интерфейса, предоставляемых хорошо продуманной объектной моделью передачи сообщений, значительно облегчают изменение и поддержание критического кода без широкого рефакторинга.
Уровни обслуживания, созданные ADM, но, безусловно, легче реализовать (поскольку они требуют относительно мало мысли и имеют множество децентрализованных точек интерфейса), вероятно, создадут проблемы в будущем, когда придет время изменить живую и растущую систему.
Я могу добавить также, что не все случаи вообще требуют модель домена (не говоря уже о ADM). Иногда лучше использовать более процедурный/функциональный стиль задачи управляется данными и не зависит от логики/бизнес-правил всей области.
Если вы пытаетесь решить все плюсы и минусы для целого приложения, я думаю, что важно сначала спроектировать, как каждый может выглядеть для вашего приложения, прежде чем вы даже начнете писать одну строку кода. После того, как вы создали CRC'd или подключили к кадру ваше приложение в обоих стилях, сделайте шаг назад и решите, какой из них имеет больше смысла и лучше подходит для приложения.
Также подумайте заранее, к чему легче будет поддерживать...
Ответ 15
Это дает лучшую предсказуемость. Такие менеджеры, особенно если проекту платят время и материалы. Каждое изменение означает большую работу, поэтому сложная работа может быть скрыта за множеством повторяющихся работ. В хорошо продуманной DRY-системе предсказуемость очень плоха, поскольку вы постоянно делаете новые вещи.
Ответ 16
модель анемичного домена - это анти-шаблон. У анти-шаблонов нет профи.