2
votes

I am reviewing areas where I can optimize the design for my mortgage calculation tool, mostly for learning purposes. After reading about Anemic Domain Models, I became interested in creating Rich Models, and noticed that my current implementation might have anemia! Here is the current implementation in pseudocode:

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;
}

Currently the Mortgage object serves primarily for data-transfer between objects, etc.

Here are some revision options I am considering:

  1. Remove Mortgage object out of the MortgageCalculator and use Mortgage purely as a DTO while the calculator's methods take arguments (e.g, calculateMonthlyPayment(loanAmount,interestRate). This would help with decoupling MortgageCalculator from the Mortgage object, but would still have Mortgage as an anemic model.
  2. Merge both classes into one "rich" MortgageCalculator model, which contains both the business logic (e.g, calculateMonthlyPayment) and mortgage properties (e.g, loanAmount). My concern here is that I am not sure if it is necessary for a calculator object to hold its operands as instance variables, but they would facilitate data transfer, storage and perhaps resolve the anemia?

I am wondering what the ideal approach would be, or if I am missing the point?

3

3 Answers

3
votes

Perhaps the Mortgage object can perform parts of the calculation. For example, consider an object that calculates an order total:

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

This is a known as Feature Envy, and could be:

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

MortgageCalculator is not actually domain entity because it is not populated into database, so to avoid anemic you can merge logic into Mortgage entity:

class Mortgage {
   loanAmount;
   interestRate;

   calculateMonthlyPayment();
}

Another thing: DTO is different with domain entity, DTO is for transferring data in distribution environment, whereas domain entity is to focus on domain logic.

You can use domain entity as DTO because in some cases, DTO has the same properties with Domain Entity. But, most of cases, depend on each clients, maybe they need to get data which requires more than one domain entities. So, for separation of concern and more maintainable, it would be suggested to create DTO separated with domain entity:

class MortgageDto {
   loanAmount;
   interestRate;
}
0
votes

You can't do DDD if you don't know your bounded contexts (BC). So what is the BC in this case? Because all depends on that.

Form what I understand in your case, I think it's good you have a MortageCalculator , because you can have multiple ways of calculating a mortgage . This class can have amethod which wiil take a Mortgage argument. OF course, what I've said can be wrong because I don't know your domain.

It's always hard to anwser a concrete question about DDD if one doesn't happen to be an expert in the required domain. But all starts with the BC so again, what is your BC and what is the business role of the Mortgage?