µ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.

Summary

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.

Show Comments