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.