Home > Net >  Given 3 factors for price, what is best way to do logic for price
Given 3 factors for price, what is best way to do logic for price

Time:04-26

I am a junior developer (bootcamp no CS background) currently working on product pricing. I am reaching out to this great community for advice.

Price is based on 3 factors with multiple levels:

Color: White, Blue, Red, Green Size: Small, medium, large Material: Cotton, Silk, Rayon

What I've tried: If-else control flow but knowing that we will be adding more materials and colors soon, this if else will be longer and slower.

if color == "white" and material == "cotton"
   price = 5 if size == "small" || size == "medium"
   price = 6 if size == "large"
elsif color == "white" and material == "rayon"
   price = 6 if size == "small" || size == "medium"
   price = 7 if size == "large"
.
.
.
end

What will be the best implementation or approach for pricing that takes into account that more levels and factors will be added in the future?

Any advise that will point me to the solution will be greatly appreciated.

CodePudding user response:

I'm making business assumptions here, but I'm guessing the different materials, colors, etc, are acting as a price modifier. I.e., given a base product (say, a t-shirt), it has a base price of 5, and then choosing some materials/sizes adds cost.

If that's the case, I might recommend implementing a PriceModifierPolicy object, which defines constants, and uses the symbols base price passed in to "determine" the total price. I.e.

class PriceModifierPolicy
  COLOR_PRICE_MODIFIER_MAP = {
    white: 1,
    gray: 1,
    black: 2
  }

  MATERIAL_PRICE_MODIFIER_MAP = {
    cotton: 0,
    rayon: 1
  }

  SIZE_PRICE_MODIFIER_MAP = {
    small: 0,
    medium: 0,
    large: 1
  }

  def initialize(base_price, color, material, size)
    @base_price = base_price
    @color = color
    @material = material
    @size = size
  end

  def compute_final_price!
    final_price = @base_price   color_price_modifier
    final_price  = material_price_modifier
    final_price  = size_price_modifier
    final_price
  end

  def color_price_modifier
    COLOR_PRICE_MODIFIER_MAP[@color]
  end

  def material_price_modifier
    MATERIAL_PRICE_MODIFIER_MAP[@material]
  end

  def size_price_modifier
    SIZE_PRICE_MODIFIER_MAP[@size]
  end
end

The benefit of this approach is that you can replace the base_price with the product you want to price, and then implement this as an inheritable BasePriceModifierPolicy that contains/can query knowledge (from a db), about given pricing modifiers for a given product. I.e.

class BasePriceModifierPolicy
  COLOR_PRICE_MODIFIER_MAP = {
    white: 1,
    gray: 1,
    black: 2
  }

  MATERIAL_PRICE_MODIFIER_MAP = {
    cotton: 0,
    rayon: 1
  }

  SIZE_PRICE_MODIFIER_MAP = {
    small: 0,
    medium: 0,
    large: 1
  }

  def initialize(product, color, material, size)
    @base_price = product
    @color = color
    @material = material
    @size = size
  end

  def compute_final_price!
    final_price = @base_price   color_price_modifier
    final_price  = material_price_modifier
    final_price  = size_price_modifier
    final_price
  end

  def color_price_modifier
    raise NotImplementedError
  end

  def material_price_modifier
    raise NotImplementedError
  end

  def size_price_modifier
    raise NotImplementedError
  end
end

class ShirtPriceModifierPolicy < BasePriceModifierPolicy
  COLOR_PRICE_MODIFIER_MAP = {
    white: 3,
    gray: 2,
    black: 5
  }

  MATERIAL_PRICE_MODIFIER_MAP = {
    cotton: 1,
    rayon: 2
  }

  SIZE_PRICE_MODIFIER_MAP = {
    small: 1,
    medium: 2,
    large: 3
  }

  def color_price_modifier
    COLOR_PRICE_MODIFIER_MAP[@color]
  end

  def material_price_modifier
    MATERIAL_PRICE_MODIFIER_MAP[@material]
  end

  def size_price_modifier
    SIZE_PRICE_MODIFIER_MAP[@size]
  end
end

If you don't need to support different products, only an ever-expanding list of add-ons. Then checkout the decorator pattern.

CodePudding user response:

I think beside the oop point of view, and if I undrestand you correctly, then you could come up with an hash object like :

[
  { 
    color=>"white",
    material=>"Cotton",
    size=>"medium", 
    price=>5
  }, ...
]

and then by iterating over the list you satisfy the request against each one and when in future you add more parameters you wont need to change the code. but this is the most basic approach , you should come up with variant object then a satisfying function to make it more versatile.

  • Related