Jason Warner
1 min readMar 31, 2022

--

The old way is more brittle and caused lots of issues because of the degree of coupling and information you needed to make something work. Before inversion of control, you would have preparePizza() do the work of grandmaPizzaPreparer. For example, without inversion of control, preparePizza() might look like:

function preparePizza() {

const recipe = GrandmasPizzaRecipe();

const dryIngredients = measure(recipe.dryIngredients);

const wetIngredients = measure(recipe.wetIngredients);

const dough = mix(recipe.dryIngredients, recipe.wetIngredients);

knead(dough);

flatten(dough);

const base = addSauce(dough, spicyMarinara);

const pizza = addIngredients(dough, pepperoni, cheese, jalapeno);

const bakedPizza = bake(pizza, 350, 35);

return bakedPizza;

}

As you can see, this violates a lot of solid rules, but was very common to see back in the day. Also, if you wanted to add a step to rest the dough, you had to make changes. If you wanted to make a mild pizza, you had to add a parameter to preparePizza() that could be passed to addSauce(). It became more and more difficult to maintain as making a pizza became more complicated.

Instead, if you have an interface for a PizzaPreparer, then you can have a MildGrandmasPizzaPreparer, a SpicyGrandmasPizzaPreparer or even a CauliflourCrustGrandmasPizzaPreparer. These can be chose at run time. Now the concrete class that does pizza preparation prepares its pizza and only its pizza. If tweaks need to be made, you can tweak that one pizza and not have issues. This is the power of inverting dependencies.

--

--

Jason Warner
Jason Warner

Written by Jason Warner

I enjoy everything related to code and being a dev. However, my only skills are showing up and being lucky and I'm not sure if luck is a talent.

Responses (2)