How can I improve this price calculator by doing 4 calculations now, but more in the near future?

I'm trying to figure out how to improve some of the code that I wrote, which uses several rules to calculate several different prices for car insurance. Here is the part that bothers me:

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;
}

Please note that there is a significant difference in the calculation of monthly payments at the regular price (annual payment), and also depending on whether BrandDealer is true or false, there is another calculation. I tried to eliminate this variable, but the client requires these rules.

I know that some of the properties are not the actual properties of Car, but I will also be refactoring.

, 4 , . .

- , , ?

+5
3

-, , , .

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...
   }

}

GetInsurance InsuranceFactory :

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), . , . , .

, . , . , 2 (Brand PaySchedule), 2 , 2 x 2 = 4 . , CreditScore (Goor, Fair, Poor). :

GoodCreditBrandDealerYearlyPaymentCalculation
GoodCreditBrandDealerMonthlyPaymentCalculation
GoodCreditNonBrandDealerYearlyCalculation
GoodCreditNonBrandDealerMonthlyCalculation
FairCreditBrandDealerYearlyPaymentCalculation
FairCreditBrandDealerMonthlyPaymentCalculation
FairCreditNonBrandDealerYearlyCalculation
FairCreditNonBrandDealerMonthlyCalculation
PoorCreditBrandDealerYearlyPaymentCalculation
PoorCreditBrandDealerMonthlyPaymentCalculation
PoorCreditNonBrandDealerYearlyCalculation
PoorCreditNonBrandDealerMonthlyCalculation

. , , , . , Calculation. , GetInsurance - .

+3

, . . , calc 1 = A * B + C. calc 2 = A * C - b

A, B, C hashmap. calc 2 = hash.getOrAdd() * hash.getOrAdd( C) - hash.getOrAdd( C).

comon, , .

0

, , , , , 4 Car. ? 4 , ( ), BrandDealer/MonthlyPayment, CarData?

In addition, this can be better achieved with some kind of calculation factory, which abstracts / hides various necessary Automotive objects and other calculation details. Consider adding internal methods for each type of calculation, so for new calculations you just need to add another method instead of changing one large method. This is usually achieved by adding computation objects instead of methods, but this may be excessive for this particular situation.

0
source

All Articles