Sunday, April 7, 2019

Interesting Talk: "In Search of Doors"

I've just watched this wonderful and inspiring talk by V.E. Schwab

The Beverages Prices Refactoring kata: a kata to practice refactoring away from an awful application of inheritance.

I created the Beverages Prices Refactoring kata for the Deliberate Practice Program I’m running at Lifull Connect offices in Barcelona (previously Trovit). Its goal is to practice refactoring away from a bad usage of inheritance.

The code computes the price of the different beverages that are sold in a coffe house. There are some supplements that can be added to those beverages. Each supplement increases the price a bit. Not all combinations of drinks and supplements are possible.

Just having a quick look at the tests of the initial code would give you an idea of the kind of problems it might have:

package unit_tests;
import beverages.*;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.closeTo;
public class BeveragesPricingTest {
private static final double PRECISION = 0.001;
@Test
public void computes_coffee_price() {
Beverage coffee = new Coffee();
assertThat(coffee.price(), is(closeTo(1.20, PRECISION)));
}
@Test
public void computes_tea_price() {
Beverage tea = new Tea();
assertThat(tea.price(), is(closeTo(1.50, PRECISION)));
}
@Test
public void computes_hot_chocolate_price() {
Beverage hotChocolate = new HotChocolate();
assertThat(hotChocolate.price(), is(closeTo(1.45, PRECISION)));
}
@Test
public void computes_tea_with_milk_price() {
Tea teaWithMilk = new TeaWithMilk();
assertThat(teaWithMilk.price(), is(closeTo(1.60, PRECISION)));
}
@Test
public void computes_coffee_with_milk_price() {
Coffee coffeeWithMilk = new CoffeeWithMilk();
assertThat(coffeeWithMilk.price(), is(closeTo(1.30, PRECISION)));
}
@Test
public void computes_coffee_with_milk_and_cream_price() {
Coffee coffeeWithMilkAndCream = new CoffeeWithMilkAndCream();
assertThat(coffeeWithMilkAndCream.price(), is(closeTo(1.45, PRECISION)));
}
@Test
public void computes_hot_chocolate_with_cream_price() {
HotChocolateWithCream hotChocolateWithCream = new HotChocolateWithCream();
assertThat(hotChocolateWithCream.price(), is(closeTo(1.60, PRECISION)));
}
}

If that’s not enough have a look at its inheritance hierarchy:

To make things worse, we are asked to add an optional cinnamon supplement that costs 0.05€ to all our existing catalog of beverages. We think we should refactor this code a bit before introducing the new feature.

We hope you have fun practicing refactoring with this kata.

Thursday, April 4, 2019

Books I read (January - March 2019)

January
- Timeless Laws of Software Development, Jerry Fitzpatrick
- Writing to Learn, William Zinsser
- The End of the Affair, Graham Greene
- Beyond Legacy Code: Nine Practices to Extend the Life (and Value) of Your Software, David Scott Bernstein

February
- Refactoring Workbook, William C. Wake
- Binti, Nnedi Okorafor

March
- Home, Nnedi Okorafor
- The Night Masquerade, Nnedi Okorafor
- Developer Hegemony, Erik Dietrich
- The Ministry of Utmost Happiness, Arundhati Roy