У меня есть приложение, которое я пытаюсь построить по крайней мере с номинальной моделью домена типа DDD, и я борюсь с определенной частью.
Моя сущность имеет некоторую бизнес-логику, которая использует некоторые финансовые расчеты и расчеты ставок, которые у меня есть в настоящее время в некоторых доменных службах, а также некоторые постоянные значения, которые я помещаю в объект значения.
Я борюсь с тем, как заставить сущность использовать логику внутри доменных сервисов, или же принадлежит ли логика внутри этих сервисов. Это то, что я до сих пор:
public class Ticket
{
public Ticket(int id, ConstantRates constantRates, FinancialCalculationService f, RateCalculationService r)
{
Id = id;
ConstantRates = constantRates;
FinancialCalculator = f;
RateCalculator = r;
}
private FinancialCalculationService FinancialCalculator { get; set; }
private RateCalculationService RateCalculator { get; set; }
private ConstantRates ConstantRates { get; set; }
public int Id { get; private set; }
public double ProjectedCosts { get; set; }
public double ProjectedBenefits { get; set; }
public double CalculateFinancialGain()
{
var discountRate = RateCalculator.CalculateDiscountRate(ConstantRates.Rate1, ConstantRates.Rate2,
ConstantRates.Rate3);
return FinancialCalculator.CalculateNetPresentValue(discountRate,
new[] {ProjectedCosts*-1, ProjectedBenefits});
}
}
public class ConstantRates
{
public double Rate1 { get; set; }
public double Rate2 { get; set; }
public double Rate3 { get; set; }
}
public class RateCalculationService
{
public double CalculateDiscountRate(double rate1, double rate2, double rate3 )
{
//do some jibba jabba
return 8.0;
}
}
public class FinancialCalculationService
{
public double CalculateNetPresentValue(double rate, params double[] values)
{
return Microsoft.VisualBasic.Financial.NPV(rate, ref values);
}
}
Мне кажется, что часть этой логики вычислений принадлежит этим доменным службам, но мне не очень нравится, что мне придется вручную вводить эти зависимости из моего репозитория. Есть ли альтернативный способ, которым это должно быть смоделировано? Я ошибаюсь, что мне это не нравится?
Прочитав «Синюю книгу», но на самом деле ничего такого в этом стиле не построил, я ищу руководство.
EDIT
Спасибо всем за отзывы! Исходя из того, что я слышу, похоже, что моя модель должна выглядеть следующим образом. Это выглядит лучше?
public class Ticket
{
public Ticket(int id)
{
Id = id;
}
private ConstantRates ConstantRates { get; set; }
public int Id { get; private set; }
public double ProjectedCosts { get; set; }
public double ProjectedBenefits { get; set; }
public double FinancialGain { get; set; }
}
public class ConstantRates
{
public double Rate1 { get; set; }
public double Rate2 { get; set; }
public double Rate3 { get; set; }
}
public class FinancialGainCalculationService
{
public FinancialGainCalculationService(RateCalculationService rateCalculator,
FinancialCalculationService financialCalculator,
ConstantRateFactory rateFactory)
{
RateCalculator = rateCalculator;
FinancialCalculator = financialCalculator;
RateFactory = rateFactory;
}
private RateCalculationService RateCalculator { get; set; }
private FinancialCalculationService FinancialCalculator { get; set; }
private ConstantRateFactory RateFactory { get; set; }
public void CalculateFinancialGainFor(Ticket ticket)
{
var constantRates = RateFactory.Create();
var discountRate = RateCalculator.CalculateDiscountRate(constantRates.Rate1, constantRates.Rate2,
constantRates.Rate3);
ticket.FinancialGain = FinancialCalculator.CalculateNetPresentValue(discountRate,
new[] {ticket.ProjectedCosts*-1, ticket.ProjectedBenefits});
}
}
public class ConstantRateFactory
{
public ConstantRates Create()
{
return new ConstantRates();
}
}
public class RateCalculationService
{
public double CalculateDiscountRate(double rate1, double rate2, double rate3 )
{
//do some jibba jabba
return 8.0;
}
}
public class FinancialCalculationService
{
public double CalculateNetPresentValue(double rate, params double[] values)
{
return Microsoft.VisualBasic.Financial.NPV(rate, ref values);
}
}
Модель предметной области в конечном итоге оказывается довольно анемичной, но, поскольку я добавляю функции, возможно, у нее будет больше.
РЕДАКТИРОВАТЬ 2
Хорошо, я получил еще несколько отзывов о том, что, возможно, мои «расчетные» сервисы больше похожи на объекты стратегии, от которых вполне может зависеть моя сущность. Вот еще один пример с большей логикой в сущности и использованием этих стратегических объектов. Мысли об этом? Есть ли какие-либо проблемы с созданием экземпляров этих помощников непосредственно в организации? Не думаю, что мне захочется их высмеивать в моих тестах, но ОТО, я не могу протестировать метод CalculateFinancialGain без тестирования этих объектов стратегии.
public class Ticket
{
public Ticket(int id, ConstantRates constantRates)
{
Id = id;
ConstantRates = constantRates;
}
private ConstantRates ConstantRates { get; set; }
public int Id { get; private set; }
public double ProjectedCosts { get; set; }
public double ProjectedBenefits { get; set; }
public double CalculateFinancialGain()
{
var rateCalculator = new RateCalculator();
var financeCalculator = new FinanceCalculator();
var discountRate = rateCalculator.CalculateDiscountRate(ConstantRates.Rate1, ConstantRates.Rate2,
ConstantRates.Rate3);
return financeCalculator.CalculateNetPresentValue(discountRate,
ProjectedCosts*-1,
ProjectedBenefits);
}
}
public class ConstantRates
{
public double Rate1 { get; set; }
public double Rate2 { get; set; }
public double Rate3 { get; set; }
}
public class RateCalculator
{
public double CalculateDiscountRate(double rate1, double rate2, double rate3 )
{
//do some jibba jabba
return 8.0;
}
}
public class FinanceCalculator
{
public double CalculateNetPresentValue(double rate, params double[] values)
{
return Microsoft.VisualBasic.Financial.NPV(rate, ref values);
}
}