首先,让我们解决您今天遇到的问题,这是一种清理重复计算代码的方法。
首先,我们需要将 Stratgey 模式应用到您的价格计算中,定义计算接口并将不同的计算逻辑代码移动到它们的新位置:
// 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
) 中的列表中,您的保险类别也不需要更改。您的 UI 代码可以通过迭代该列表来呈现所有选项。这个例子稍微简化了一点,但应该可以帮助你。
现在谈谈我可以预料到的可能的第二个问题。如果你的计算子类开始有额外的排列,你将会有一个类爆炸。例如,现在您有 2 个因素(Brand 和 PaySchedule),每个因素有 2 个选择,给您 2 x 2 = 4 个类。但是,如果我们将 CreditScore 添加到其中,有 3 个选项(Goor、Fair、Poor)会怎样。然后你得到:
GoodCreditBrandDealerYearlyPaymentCalculation
GoodCreditBrandDealerMonthlyPaymentCalculation
GoodCreditNonBrandDealerYearlyCalculation
GoodCreditNonBrandDealerMonthlyCalculation
FairCreditBrandDealerYearlyPaymentCalculation
FairCreditBrandDealerMonthlyPaymentCalculation
FairCreditNonBrandDealerYearlyCalculation
FairCreditNonBrandDealerMonthlyCalculation
PoorCreditBrandDealerYearlyPaymentCalculation
PoorCreditBrandDealerMonthlyPaymentCalculation
PoorCreditNonBrandDealerYearlyCalculation
PoorCreditNonBrandDealerMonthlyCalculation
这只会从这里变得更糟。如果出现,这确实值得自己提问和回答,但这是您应该注意的事情。如果它开始变成这样,请重构 Calculation 类。但好的是 GetInsurance 中的代码仍然不需要更改。