/ 20180110

µObjects: Pizza Shop - Calzoned!

The pizza shop is expanding it's offerings! CALZONES!

We'll do a 1/2 calzone and a full calzone! $8 and $14 respectively.

Based on how we did the Medium pizza last time... Not expecting much work for these. Which... THAT'S THE POINT! µObjects make this easy.

Removing a topping... Excellent. A new behavior. New behaviors are where modificaations get interesting. Medium Pizza and Calzones; that's more of the same behavior.

Let's get the calzone's out of the way... I mean... Let's implement our clients new offerings!
Then do the new stuff... I mean... Then allow customers to change their mind.

Looking through the code I see that the "pizza" in the descriptions is hard coded pretty deep in. This will need to be changed for calzones. Not hitting it quite yet; but wanted to point it out here. Checking through some code before you begin may help later identify places where you'll have to make changes.

OK - Code time.

I'm starting with the 1/2 calzone.
Doing the price first.
I'm going to C&P a pizza; throw exceptions for each non-implemented piece. Unlike when I did the medium and left the large values in. Didn't like that much.

Which made my first test fail. Good. So much nicer when it's Red first. I am still cheating a bit by the copy and paste; I know that. The focus here is on the µObjects more than the TDD aspect. We have tests. It's the only way to develop. But as I do in kata's - I pick a focus to do very strictly, a secondary to include. This time; µObjecting is the primary. Testing is going to be let a little loose for these examples.

I've created the HalfCalzone and have the price working in commit e2012bf where I also moved a bunch of files.... which I forgot to commit first.

Next up is the larger required change - Description. Not sure how this will play out... EXCITING!
First we need to add a type. I use NCrunch to run tests real time. It's nice enough that I've bought a personal license for it. Much like I have for Resharper. I have the JetBrains All Products Pack and, for me, totally worth it.
OK - Back to pizza... errr.... Calzones.
NCrunch is showing where the exception is; and it's on trying to get the type. Which makes a bit of sense since the type is what the description is built off of.

Adding a HalfCalzone to PizzaType gets rid of the exception; but we're not the right result.
I think the simplest would be to pull pizza into the PizzaType. Simple is the way to go... Let's try it.
It makes a bit more sense this way, now.

Changed PizzaType slugs to have "pizza" in their descriptor. Fixing the HalfCalzone to be "1/2 Calzone" and now passing.
We had to take out pizza from the NoToppingsPizzaDescriptionAction and ToppingsPizzaDescriptionAction as seen in commit f068583
The last bit for our 1/2 calzone is adding toppings.

Done with 1/2 calzone in commit 1bbf5c0. For the Full Calzone; it's a C&P of the 1/2 calzone and it's tests.

I'm gonna do the entire batch for focus reasons. I want to get to the new behavior in this example.

Did the quick addition of a Full Calzone. Updated everything... Works. All test pass. This is a cheat - Do this working production code; there's some hand slapping.
Check out commit 8aeb3f8 for the cheaty details.

Remove a topping

And now... Removing a topping! Which is mostly just like adding a topping. But let's get a test in place... which looks like a add topping test...

Using a test for adding three toppings; I remove one via the RemoveTopping method... which doesn't exist.
Hmm... going into this. I'm adding a method to both Pizza and Toppings via one test. While... Yes. This will work. It's not right.
I can cheat a bit; but I need to write tests around Toppings for this addition. It's not refactoring behavior into a class and confirming by existing tests; it's new behavior. It needs TDD.
A git reset --hard later; and we'll write some ToppingsTests.
A test to ensure removing something not already present does not throw.
Simple enough
If you looked at that you may notice that I have some lines commented out - mostly lazy.
But I need them commented out so my next test goes red. We're adding a topping, removing a topping; and the added-pizza should not change. We're dealing with strict immutability in this project.

... Always interfaces. Just now added Remove(ITopping) to the interface... Always interfaces.

We successfully remove a topping from the toppings in commit f090d15

We extend the successful to removing a topping from a pizza w/immutability in commit b5bfbbf.

A bit of refactoring... and our second change set to our Pizza Shop is complete.


This is showing the power of µObjects to adapt to changes to a system. While not extensive examples; single changes aren't.
If you are dealing with an extensive change - It's too big. Break it down. Keep breaking it down until there's a small change that can be done.
Don't break tests during changes. :) If you do, you're doing too much.

Next change set is a little more hefty. I added a couple twists to it. I want to see if it highlights what µObjects can do for maintainability of the code.

Quinn Gil

Code Artisan beating the drum of Development Best Practices. Extreme Programming and Object Oriented Design.

Read More