まず、現在の問題を解決しましょう。これは、繰り返し計算コードをクリーンアップする方法です。
まず、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と呼びます)内で、コンストラクターでこれを行います。これは、プロパティ、構成、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つの要素(ブランドとPaySchedule)があり、それぞれに2つの選択肢があり、2 x 2=4のクラスがあります。しかし、3つの選択肢(Goor、Fair、Poor)を使用してCreditScoreを追加するとどうなりますか。次に、次のようになります。
GoodCreditBrandDealerYearlyPaymentCalculation
GoodCreditBrandDealerMonthlyPaymentCalculation
GoodCreditNonBrandDealerYearlyCalculation
GoodCreditNonBrandDealerMonthlyCalculation
FairCreditBrandDealerYearlyPaymentCalculation
FairCreditBrandDealerMonthlyPaymentCalculation
FairCreditNonBrandDealerYearlyCalculation
FairCreditNonBrandDealerMonthlyCalculation
PoorCreditBrandDealerYearlyPaymentCalculation
PoorCreditBrandDealerMonthlyPaymentCalculation
PoorCreditNonBrandDealerYearlyCalculation
PoorCreditNonBrandDealerMonthlyCalculation
これはここから悪化するだけです。これは、それが出てきた場合、それ自体の質問と回答の価値がありますが、注意する必要があります。このようになり始めたら、Calculationクラスをリファクタリングします。しかし、すばらしいのは、GetInsuranceのコードを変更する必要がないことです。