Skip to content

Refactoring – Flocking rules

I have always been a fan of Sandi Metz, and have finally got around to her book 99 Bottles of OOP. A key takeaway so far from this has been the flocking rules for refactoring. The name derives from the small changes an individual bird makes in a flock that is then reflected by all the other birds so everyone ends up going in the right direction.

The premise is fairly simple, make small incremental changes that only change a single thing a time. A lot of people think they do this already, however small is not small enough in many cases. A change to a whole function in one go is not a small change – the impact of something going missing could be huge.

Lets have a look at a very simple function below

public static string PrintMySpiritAnimal()
{
    var message = "My spirit animal is a horse";
    return message;
}

As you can see, this function prints every spirit animal as a horse. Maybe a developer forgot to extract it when developing the application. Now, we could go all guns blazing and go straight to the end point, which is a method that will probably look something like this.

public static string PrintMySpiritAnimal(string animal)
{
    return $"My spirit animal is a {animal}";
}

Looks good right? We can see the intent of what the original developer was trying to do, and we have implemented the solution fully. Trivial. Except it isn’t. Especially in a language like say, JavaScript, that won’t throw compiler warning at you. Can you see the issue?

Everywhere that was originally calling that method will have probably called it without parameters. If that ends up in live, there will be a lot of errors!

So lets use flocking rules! First off, a test that mimics the current live implementation and passes it!

[Test]
public void ReturnSpiritAnimal()
{
    var result = SpiritGuru.PrintMySpiritAnimal();
    Assert.IsTrue(result, "My spirit animal is a horse");
}

Great, now we can make the smallest change possible that will still pass the test.

public static string PrintMySpiritAnimal()
{
    var animal = "horse"
    var message = "My spirit animal is a " + animal;
    return message;
}

The animal is now extracted into a variable and the message uses that variable to print the spirit animal. The test still passes. Now we can refine that further.

public static string PrintMySpiritAnimal(string animal = "horse")
{
    var message = "My spirit animal is a " + animal;
    return message;
}

Now we can see that we can probably pass in that variable to the method, and we can implement it using the same logic that it defaults to “horse”. The test still passes! Brilliant.

The next iteration you might be tempted to remove the default, at which point the test will break and the light bulb go off. By repeated changes to the smallest possible thing, we can ensure that our tests always stay green and that we don’t miss anything out!

This is a very basic recreation of what Sandi does in 99 bottles of OOP and I suggest everyone give it a read for the full experience!

Published inConcepts

Comments are closed.