Пример решения анемичной доменной модели

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

class MortgageCalculator {
  Mortgage mortgage; // mortgage object containing loanAmount, interest rate, etc.;
  calculateMonthlyPayment(); // calculates monthly payments using mortgage object's properties
}

class Mortgage { // Anemic?
  loanAmount;
  interestRate;
}

В настоящее время объект ипотеки служит преимущественно для передачи данных между объектами и т. Д.

Вот несколько вариантов ревизии, которые я рассматриваю:

  1. Удалите объект Mortgage из MortgageCalculator и используйте Mortgage исключительно как DTO, в то время как методы калькулятора принимают аргументы (например, calcMonthlyPayment(loanAmount, InterestRate). Это поможет отсоединить MortgageCalculator от объекта Mortgage, но при этом все равно будет иметь Mortgage в качестве анемичной модели,
  2. Объедините оба класса в одну "богатую" модель MortgageCalculator, которая содержит как бизнес-логику (например, calcMonthlyPayment), так и свойства ипотеки (например, loanAmount). Меня беспокоит то, что я не уверен, нужно ли объекту калькулятора хранить свои операнды в качестве переменных экземпляра, но они облегчили бы передачу, хранение данных и, возможно, разрешили бы анемию?

Мне интересно, какой будет идеальный подход, или я упускаю суть?

3 ответа

Возможно, Mortgage Объект может выполнять части расчета. Например, рассмотрим объект, который вычисляет сумму заказа:

for (Line line : orderLines)
  int total += line.getPrice() * line.getQuantity();

Это известно как Feature Envy, и может быть:

for (Line line : orderLines)
  int total += line.calculateTotal();

MortgageCalculator на самом деле не является сущностью домена, потому что она не заполняется в базе данных, поэтому, чтобы избежать анемии, вы можете объединить Mortgage юридическое лицо:

class Mortgage {
   loanAmount;
   interestRate;

   calculateMonthlyPayment();
}

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

Вы можете использовать доменную сущность в качестве DTO, потому что в некоторых случаях DTO имеет те же свойства, что и Domain Entity. Но, в большинстве случаев, зависит от каждого клиента, возможно, им нужно получить данные, для которых требуется более одного объекта домена. Таким образом, для разделения проблем и обеспечения большей поддержки было бы предложено создать DTO, разделенный сущностью домена:

class MortgageDto {
   loanAmount;
   interestRate;
}

Вы не можете делать DDD, если не знаете своих ограниченных контекстов (BC). Так что же такое БК в этом случае? Потому что все зависит от этого.

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

Всегда трудно ответить на конкретный вопрос о DDD, если не случается, что он является экспертом в требуемой области. Но все начинается с БК, поэтому снова, каков ваш БК и какова бизнес-роль Ипотеки?

Другие вопросы по тегам