当我试图遵循单一责任原则时,我常常发现自己处在一个有太多事情可做的境地,我不知道从哪里开始。也许有一条经验法则可以让我用?
一个源自我的测试项目的具体例子。
// doing way too many things
public InvoiceDto GetInvoice(CartDto cart)
{
if (cart == null)
throw new ArgumentNullException(nameof(cart)); // validation
var cartequipments = _carts.GetById(cart.CartId).CartEquipments.ToList(); // quering
var rentals = cartequipments.Select(o => // mapping
new RentalDto // object creation
{
Name = o.Equipment.EquipmentName,
Price = _mapPriceCalculatorLogic // buisiness logic
.Create(o.Equipment.EquipmentType)
.Calculate(o.RentDurationDays)
}).ToList();
var loyaltyPoints = _loyaltyPointsService // buisiness logic
.GetLoyaltyPoints(cartequipments.Select(o => o.Equipment.EquipmentType));
var total = rentals.Sum(o => o.Price); // aggregation
var invoiceDto = new InvoiceDto // object creation
{
Title = $"Invoice id : {cart.CartId}",
Rentals = rentals,
LoyaltyPoints = loyaltyPoints,
TotalPrice = total
};
return invoiceDto;
}我的问题是,您将如何清理这个问题,如果可能的话,结果会是什么样子(不需要帮助方法源)。
发布于 2016-05-19 11:23:56
制定从手推车中获取设备、从设备中租赁、从设备中获取忠诚度点、从租赁点和忠诚点创建发票的单独方法。
发布于 2016-05-19 13:03:28
您的代码格式良好,易于阅读。祝贺你。
关于SRP,我相信您的代码符合很好。每个依赖项:购物车、租金和忠诚度点是通过一个调用来检索的。这些DTO的映射是用一个小的、单一用途的匿名方法来隔离的。该方法的单个责任与其名称GetInvoice匹配。
如果您不喜欢匿名方法与定义它们的方法分开的想法,请考虑在该方法的类中创建私有静态命名方法并引用它们。
我唯一关心的SRP违规行为是发票DTO。我建议使用原始购物车id,并让您的演示代码格式化标题。
下面是我如何清理它的一个例子:
public InvoiceDto GetInvoice(CartDto cart)
{
if (cart == null)
throw new ArgumentNullException(nameof(cart));
var cartequipments = _carts.GetById(cart.CartId).CartEquipments.ToList();
var rentals = cartequipments.Select(o => MapEquipmentToRentalDto).ToList();
var loyaltyPoints = _loyaltyPointsService
.GetLoyaltyPoints(cartequipments.Select(o => o.Equipment.EquipmentType));
var total = rentals.Sum(o => o.Price);
var invoiceDto = new InvoiceDto
{
InvoiceId = cart.CartId,
Rentals = rentals,
LoyaltyPoints = loyaltyPoints,
TotalPrice = total
};
return invoiceDto;
}
private static RentalDto MapEquipmentToRentalDto(CartEquipment o)
{
return new RentalDto
{
Name = o.Equipment.EquipmentName,
Price = _mapPriceCalculatorLogic
.Create(o.Equipment.EquipmentType)
.Calculate(o.RentDurationDays)
};
}https://codereview.stackexchange.com/questions/128742
复制相似问题