我正在尝试找出如何改进我编写的一些代码,这些代码使用一些规则来计算汽车保险的一些不同定价。这是困扰我的部分:
public Insurance GetInsurance(CarData carData)
{
var insurance = new Insurance();
insurance.priceGeneral = this.CalculatePrice(new Car { BrandDealer = false, MonthPayment = false, CarData = carData });
insurance.priceGeneralMonth = this.CalculatePrice(new Car { BrandDealer = false, MonthPayment = true, CarData = carData });
insurance.priceBrandDealer = this.CalculatePrice(new Car { BrandDealer = true, MonthPayment = false, CarData = carData });
insurance.priceBrandDealerMonth = this.CalculatePrice(new Car { BrandDealer = true, MonthPayment = true, CarData = carData });
return insurance;
}
请注意,计算月付款与正常价格(年付款)有很大差异,并且取决于 BrandDealer 是真还是假,也有不同的计算方式。我试图消除这个变量,但客户要求这些规则。
我知道有些属性不是“汽车”的实际属性,但我也会尽快对其进行重构。
我很烦这个计算我做了4次,以后还会有更多的规则。即将到来的新规则将添加另一个 bool 值和另外 2 个计算。
是否有一些我在这里没有发现但应该使用的不错的设计模式?
最佳答案
首先解决你今天遇到的问题,这是一种清理重复计算代码的方法。
首先,我们需要将 Stratgey 模式应用到您的价格计算中,定义计算接口(interface)并将不同的计算逻辑代码移到它们的新位置:
// calculation common interface
public interface IPriceCalculation
{
public InsurancePrice CalculatePrice(CarData data);
}
// result from the calculation
public class InsurancePrice
{
public string Description { get; set; }
public decimal Price { get; set; }
}
// concrete implementations
public class BrandDealerMonthlyPaymentCalculation : IPriceCalculation
{
public InsurancePrice CalculatePrice(CarData data)
{
// logic to perform calculation of BrandDealer = true, MonthPayment = true
// just for example...
return new InsurancePrice()
{
Description = "Policy price with a Brand dealer and monthly payments",
Price = 250.25;
};
}
}
public class BrandDealerYearlyPaymentCalculation : IPriceCalculation
{
public InsurancePrice CalculatePrice(CarData data)
{
// logic to perform calculation of BrandDealer = true, MonthPayment = false
}
}
public class NonBrandDealerYearlyCalculation : IPriceCalculation
{
public InsurancePrice CalculatePrice(CarData data)
{
// logic to perform calculation of BrandDealer = false, MonthPayment = false
}
}
public class NonBrandDealerMonthlyCalculation : IPriceCalculation
{
public InsurancePrice CalculatePrice(CarData data)
{
// logic to perform calculation of BrandDealer = false, MonthPayment = true
}
}
定义了计算后,您就可以安装它们了。在定义 GetInsurance 方法的类中(我们称之为 InsuranceFactory),我们将在您的 ctor 中执行此操作。这可以通过另一个类通过属性、通过配置、通过 DI 等将它们插入来完成,但是 ctor 是最简单的说明:
public class InsuranceFactory
{
private List<IPriceCalculation> _priceCalculators = new List<IPriceCalculation>();
public InsuranceFactory()
{
_priceCalculators.Add(new BrandDealerYearlyPaymentCalculation());
_priceCalculators.Add(new BrandDealerMonthlyPaymentCalculation());
_priceCalculators.Add(new NonBrandDealerYearlyCalculation());
_priceCalculators.Add(new NonBrandDealerMonthlyCalculation());
// easy to add more calculations right here...
}
}
接下来我们重新访问上面 InsuranceFactory 类中的 GetInsurance 方法:
public Insurance GetInsurance(CarData carData)
{
var insurance = new Insurance();
// iterate the different pricing models and them to the insurance policy results
foreach (IPriceCalculation calculator in _priceCalculators)
{
insurance.PriceOptions.Add(calculator.CalculatePrice(carData));
}
return insurance;
}
注意每次创建新计算时您的 GetInsurance 方法不再需要更改。同样,通过将结果存储在保险对象 (insurance.PriceOptions
) 的列表中,您的 Insurance 类也不需要更改。您的 UI 代码可以通过迭代该列表来显示所有选项。这个例子稍微简化了,但应该可以让你继续。
现在谈谈我可以预见的第二个可能的问题。如果你的计算子类开始有额外的排列,你将有一个类爆炸。例如,现在您有 2 个因素(品牌和薪酬计划),每个因素有 2 个选择,给您 2 x 2 = 4 个类别。但是,如果我们将 CreditScore 添加到其中,有 3 个选择(Goor、Fair、Poor)会怎么样。然后你得到:
GoodCreditBrandDealerYearlyPaymentCalculation
GoodCreditBrandDealerMonthlyPaymentCalculation
GoodCreditNonBrandDealerYearlyCalculation
GoodCreditNonBrandDealerMonthlyCalculation
FairCreditBrandDealerYearlyPaymentCalculation
FairCreditBrandDealerMonthlyPaymentCalculation
FairCreditNonBrandDealerYearlyCalculation
FairCreditNonBrandDealerMonthlyCalculation
PoorCreditBrandDealerYearlyPaymentCalculation
PoorCreditBrandDealerMonthlyPaymentCalculation
PoorCreditNonBrandDealerYearlyCalculation
PoorCreditNonBrandDealerMonthlyCalculation
这只会变得更糟。如果它出现,这真的值得自己提问和回答,但这是你应该注意的事情。如果它开始变得像这样,请重构 Calculation 类。但好的是 GetInsurance 中的代码仍然不需要更改。
关于c# - 我如何改进这个价格计算代码,现在进行 4 次计算,但在不久的将来会进行更多计算?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10672491/