Legacy Code: Extract-FirstUT-Cover-Refactor-TDD
Wikipedia

Legacy Code: Extract-FirstUT-Cover-Refactor-TDD

 Recently, I had the opportunity to work on legacy code with several teams from various organizations. I would like to share my experience.

We usually start by choosing a piece of code that is “painful” - changing frequently and “scary” to touch because of its complexity. We explain that our purpose is to make the code simpler, readable and easy to change. Establishing the motivation for what we do is important!

In essence, the steps we take are:

1.      Use extract method/rename to make the code more readable (specifically applicable for very long methods).

2.      Write and execute the first unit test (that’s usually the toughest part) as described by Michael Feathers.

3.      Add more unit tests until the area you want to refactor is satisfactorily covered.

4.      Refactor to make the code more maintainable (working in very small steps, as described by Joshua Kerievsky).

5.      Make the required change using TDD.

The purpose of (1) is to see the forest, not the trees. Long methods tend to be unreadable. Using “extract method” helps you see clearly what’s going on. Once you gain vision, you can start to rename. Arlo Belshee talks about this.

As an example, look at these two statements:

At the first if statement, we have extracted the condition to a method. Remember that what you do most of the time with code is reading it. Better make your code readable.

Item (2), as mentioned above, is the difficult part. You need both to master the technique and have the resolution to do it. I usually do it with the entire team and so, together, we have the required courage.

For instance, take a look at this code behemoth.

Pure fun, eh? This is something I call an amusement park method. We usually start by trying to call it with nulls. Sometimes, it actually works and we have a first unit test. Then we start to slowly fill in the parameters. Maybe instead of a null send an empty dictionary. Maybe instead of an empty dictionary send a dictionary with two entries. And if there’s no choice sometimes we run the actual application and serialize the parameters, to be deserialized in the unit test later.

Sometimes we change a method from private to public, sometimes we add a method to better control a member, and there are more vicious things we do. Sometimes it can take a whole morning to do this. However once you understand this, it becomes very simple.

Then you start looking at coverage.

Once you have the first test, things start to move faster (3). You start adding more and more tests. You start looking at coverage reports to see which lines of code are covered and which aren’t. If something is not covered, you can add another unit test to cover it.

Now (4) we can start to make bigger changes. Once you have the unit tests in place you feel free. You make a small change, you run the test. Another small step and the tests run again. Some IDEs have plug-ins that run the tests every time something is changed.

This is the time to get better familiar with the automatic refactoring tools of your IDE. Make sure you are familiar with introduce parameter, field, variable. Extract class is a very nice one and so is the ability to convert a method to static and move a method. The trick here is to make as fewer manual changes as possible and move the code around fluently.

Many times by this point, there is a small disappointment. The code you feared in the morning now looks quite simple. The real challenge is making the code simple, solving the puzzle.

Now we reached the point when we can quite easily add some code to fulfill a new requirement (5). We can add a new test, see it fail, make the required change, see it pass and maybe do a little refactoring. Nothing like the joy of seeing unit tests turn from red to green.

And that’s it.

 

 

 

 

要查看或添加评论,请登录

Yaki Koren的更多文章

  • How to change mindset - the Jahnun lesson

    How to change mindset - the Jahnun lesson

    As a coach helping organizations become agile, I'm asked how to change the mindset of the people, how to help them see…

    1 条评论
  • How to Achieve Valuable Retrospectives

    How to Achieve Valuable Retrospectives

    “Oh no, it’s retrospective time!” This cry for help is not uncommon, I’m afraid, among practitioners of scrum. That is…

  • The horrible truth about software development estimation, and what to do about it

    The horrible truth about software development estimation, and what to do about it

    The Horrible Truth In recent years I've been working with many software development teams and almost all of them…

  • A Beautiful Day For Unit Tests

    A Beautiful Day For Unit Tests

    Writing unit tests on Legacy Code is an adventure. Today I spent several hours doing that with two developers, Mark and…

  • 5 steps to get unit tests going

    5 steps to get unit tests going

    Once you start unit testing, you will find significant benefits to your design, throughput, quality and peace of mind…

    3 条评论
  • Setting Goals For Improvement - Leading vs. Lagging

    Setting Goals For Improvement - Leading vs. Lagging

    Many organizations are becoming agile to improve quality, throughput or many other good things that agile brings along.…

  • 3 steps towards better team work

    3 steps towards better team work

    Working with teams I sometimes feel that teamwork is similar to the weather: everybody talks about it but not much is…

  • The Professional Developer

    The Professional Developer

    Last week I called a technician to repair an electrical shutter that was broken. The technician did a good job in…

  • Amusement Park Methods

    Amusement Park Methods

    Sometimes you stumble upon amusement park methods. Remember the feeling when first going through the gates of a big…

  • Team Storming and Compost

    Team Storming and Compost

    A team I am working with is in the storming stage of their development. Finally.

社区洞察

其他会员也浏览了