These are the final changes for our Pizza Shop. I think a few will be interesting to implement; but nothing stands out as a "how would I...?". µObjects make it very simple and quick to get new functionality in cleanly.
One of the changes is the ability to resize our Pizza or Calzone. Customers are always starting with the medium pizza and later realizing they totally need a large.
A new type of toppings are available: Premium toppings, Roasted Garlic, Sundried Tomato's and Feta Cheese. These are 32% of the pizza price.
Seems pretty straight forward - Let's continue to revel in the power of µObjects to simplify project.
I think this is gonna be pretty straight forward. We add new
PremiumTopping : Topping with the percentage... And ... yea.
We're far enough along that implementing these is going to be done through the topping class; so we should write tests.
We're not driving implementation through the pizza. We did for most of the original toppings, which allowed us to skimp on tests for each class.
With these later additions; we need TDD them into place. Since this Pizza Shop example isn't about TEST ALL THE THINGS! I'm not being as strict about class tests as I am on production code.
We're able to throw in a couple tests to make the "PremiumTopping" and have the cost be 32% as done in commit 2e95b53.
I'm moving the class to a private inner class of Topping. We'll have to update the tests to be a specific
PremiumTopping. Which is quickly done in commit a19e725
I'll need to ensure Roasted Garlic is Roasted Garlic (yeah yeah... failing the Red part here). It is confirmed though in commit d976433. That'll be known as the commit with the wrong message... oops.
We need these tests for the next two toppings, "Sundried tomato" and "Feta Cheese".
Test and implementation are in commit 72e9d59. This has been pretty straight forward to add the additional toppings.
We want to be able to resize the pizza's and calzones. Pizzas will be pretty straight forward; but I think this will introduce a calzone type. Something I was avoiding until required.
Let's do it for pizza's... watch it fail for calzones. :)]
Starting this resize suggests a method for
Toppings... which... Yeah... Need it. So test for that to get in... then will get back to resizing. OK, now I can copy the toppings as per commit f69bfb60. Critical for setting up immutable resizing. Which I'll get back to now.
I have a resize to medium implemented in commit ee7d525 but it... reeks. It's an
AsMedium method... No... This feels like it should take the
IPizzaType as an arg... which if I add a "create" method to the type... Simple. A bit of a refactor to break out the
PizzaType slugs into private classes.
This is starting in commit 0b9c9c3 and I'm seeing a few changes coming down the pipe from this style. It'll be interesting to see where it evolves.
Gonna leave Calzones alone for the moment. To make this interesting; I'm not allowing Pizza<->Calzone. I sense envy...
I did a few things to get back to tests. It was a few too many steps at a time. I was red for a few minutes... :|
Big changes in commit b333722 is splitting pizza and calzone from a common type.
- Calzones are now neither
PizzaTypeor derived from
- Products are created from
- Added IProductType interface for the description printing
With this; the individual type classes (
HalfCalzone, ...) started to smell. A bit of refactoring got them out of the code base.
CalzoneType are starting to smell with their private classes. BTW - Private, or nested, classes are a smell.
After a bit of refactoring; these no longer have nested classes.
This concludes the Pizza Shop power hour(s) of how µObjects makes adapting code to new requirements quick and easy. Even significant refactors are straight forward and can be done slowly due to the nature of objects.
Resize was actually a much more involved refactor than I expected. I could have left it with the individual size classes, and the type classes having nested... But these are smells. We refactor smells. We've simplified the code. Literally dropped a 1/2 dozen classes because we care about having our code high quality. To add a new size of pizza; it's a single line. Before... a dozen?
Going through the files... I see that Toppings has the same inner private class structure... Time to make it go away.
Pretty quick to switch this around to not need those classes.
Again - Bigger and longer; but not harder; than expected. The classes keep behavior isolated (which is why nested classes) and hide implementation details (private nested) which allow refacors to remove them.
µObjects allowed me to sweep through and remove a lot of classes.