Cra*_*eer 11 c# domain-driven-design
我有一个应用程序,我正在尝试使用至少一个名义上的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);
}
}
Run Code Online (Sandbox Code Playgroud)
我觉得有些计算逻辑确实属于那些域服务,但我真的不喜欢我必须从我的存储库中手动注入这些依赖项.是否有另一种方式可以建模?我不喜欢那个吗?
读过蓝皮书但之前没有真正构建过这种风格的东西,我正在寻找指导.
编辑
谢谢大家的反馈!基于我所听到的,听起来我的模型看起来应该更像下面的内容.这看起来更好?
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);
}
}
Run Code Online (Sandbox Code Playgroud)
域模型在这一点上最终变得相当贫乏,但是当我添加功能时,它可能会有更多功能.
编辑2
好的,我得到了更多反馈,也许我的"计算"服务更像是战略对象,我的实体可以依赖它.这是对实体的更多逻辑的另一种看法,并利用这些策略对象.对此的想法?直接在实体中实例化这些助手的任何问题?我认为我不想在我的测试中嘲笑那些,但OTOH我也无法在不测试这些策略对象的情况下测试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);
}
}
Run Code Online (Sandbox Code Playgroud)
让您的服务接受Ticket
实体作为参数.服务应该是无状态的,同一服务应该能够为任意数量的实体提供服务.
在你情我愿拉FinancialCalculatorService
和RateCalculatorService
你的实体,并就每个服务的方法接受Ticket
实体作为参数.
花点时间阅读pg.Eric Evans的领域驱动设计105
归档时间: |
|
查看次数: |
3560 次 |
最近记录: |