gpt4 book ai didi

c# - 使用服务的 DDD 实体

转载 作者:可可西里 更新时间:2023-11-01 08:42:17 26 4
gpt4 key购买 nike

我有一个应用程序,我正在尝试使用至少一个名义上的 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);
}

}

我觉得某些计算逻辑确实属于那些域服务,但我不太喜欢我必须从我的存储库中手动注入(inject)这些依赖项。有没有其他方法可以对此进行建模?我不喜欢那个是错的吗?

我已经阅读了蓝皮书,但之前没有真正按照这种风格构建任何东西,我正在寻找指导。

编辑

感谢大家的反馈!根据我所听到的,听起来我的模型应该更像下面这样。这样更好看?

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

好的,我得到了更多反馈,也许我的“计算”服务更像是我的实体可以依赖的策略对象。这是在实体中返回更多逻辑并利用这些策略对象的另一种方法。对此有何想法?直接在实体中实例化这些助手有什么问题吗?我不认为我会想在我的测试中模拟这些,但是 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);
}

}

最佳答案

让您的服务接受 Ticket 实体作为参数。服务应该是无状态的,并且同一个服务应该能够向任意数量的实体提供服务。

在您的情况下,我会将 FinancialCalculatorServiceRateCalculatorService 从您的实体中拉出,并使每个服务上的方法接受 Ticket 实体作为一个参数。

花点时间阅读 pg. 105Domain-Driven Design by Eric Evans

关于c# - 使用服务的 DDD 实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2380882/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com