Taken from Code Kata’s by Dave Thomas
The basic premise of this Kata is asking how you would model super market pricing. What is the price of an item? What is the cost? How do you handle price-per-pound? Buy 2 get one free? What’s the value of stock? It’s interesting, and I thought I’d take the time to blog through my thought process.
I’d like to iterate over the design and see where it takes me. First task is to represent a product.
1 2 3 4 5 6 7 8 9 10 11 |
|
Basic enough… But the :price element can’t simply be a float… no it’s it’s own object… let’s look at that closer
1 2 3 4 5 6 7 8 9 10 11 |
|
At first, this looks overly complicated, but it allows us to store the exact input and calculate off of that. We never want to store $0.3333333 / orange when the user enters 3 for $1–that would make our rounding happens at the EARLIEST possible moment, rather than the latest. We also want to enable flexible definitions of what costs the amount specified, thus you could say 0.99/pound, etc. There should be some units that are known, and others that are simply treated the same a nil (or /each). I’m not thrilled with the num_free or special yet… maybe those will factor themselves differently as we go forward.
So what can we represent here… let’s set up some examples:
1 2 3 4 |
|
There’s a couple things about these that I want to refactor as I’m going… I want the price to be a bit more readable… like:
1 2 3 4 |
|
That’s what I’d like. It reads straight across. You can represent most things here… so we’ll refactor “Price” and “Product” to look like that:
1 2 3 4 5 6 7 8 9 10 11 |
|
1 2 3 4 5 6 7 8 9 10 11 |
|
There! Much better! Now how about being able to call “cost” for a specific quantity of something. Should it be on the “product” or the “price”? They are closely related, but the product is what needs the call, most likely delegating some of the calculation to the price. Let’s set up “Price.of(n)” and “Product.buy!(n)” Product.buy!(n) will actually decrease the quantity we have in stock.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
This continues to be tougher and tougher, but I’m getting the idea. This would be great for a TDD driven exercise. I’d like to do the timed Kata like Corey Heines does – to music even :)
Enough for this Kata. Time to move on to Kata #2.