Hi I was tasked with building an app with the following brief.
Implement an interface, which calculates prices based on promotional rules.
co = Checkout.new(promotional_rules)
co.scan(item)
co.scan(item)
price = co.total
Essentially, depending on the promotional rules set up, certain items are discounted accordingly.
I had some feedback on my code stating that I have encapsulated the group of promotional_rules and then exposed the rules as an array anyway – bad OO
I initially created a promotional_rules object, which contains an array of rules.
def initialize
@rules = []
end
def addrule(rule)
@rules.push(rule)
end
Then in my checkout object I have the promotional_rules object that has been setup and passed into the initializer. I loop through the array of rules contained in the promotional_rules object and apply them to the items scanned by the checkout object.
def initialize(promotionalrules=Promotionalrules.new)
@promotionalrules = promotionalrules
end
....Other code
for rule in @promotionalrules.getrules
for item in @items
##Execute rule on current item.
end
end
Im not overly happy with my code…the loop with the loop etc. But am just looking for some help with encapsulation as Im not sure where I have gone wrong.
Any suggestions on good design patterns to apply to the brief would be beneficial also, as not too confident about the approach I took. Thanks
I’d guess that they’re complaining about this “exposure”:
that bleeds the internal rules from your Promotionalrules (which probably should be called PromotionalRules) out to the caller. The fix is to reverse your logic a little bit:
and then later:
The essential change is that you apply the ruleset as a whole to each item. This hides the ruleset implementation details and, as an extra bonus, allows you to easily support rules that depend on each other (“you can get discount X unless you’re using coupon Y” and things like that).