Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you refactor?

I was wondering how other developers begin refactoring. What is your first step? How this process (refactoring) differ if you refactor code which is not yours? Do you write tests while refactoring?

like image 731
rafek Avatar asked Oct 15 '08 16:10

rafek


3 Answers

  1. do not refactor anything non-trivial that does not already have unit tests
  2. write unit tests, then refactor
  3. refactor small pieces and re-run the tests frequently
  4. stop refactoring when the code is DRY* clean

* DRY = Don't Repeat Yourself

like image 173
Steven A. Lowe Avatar answered Nov 12 '22 13:11

Steven A. Lowe


What is your first step?

The first step is to run the unit tests to make sure they all pass. Indeed, you can waste a large amount of time looking for which of your changes broke the a test if it was already broken before your modify the code.

How this process differ if you refactor code which is not yours ?

I'm certainly doing smaller steps when refactoring code I didn't write (or code I wrote a long time ago). I may also verify the test coverage before to proceed, to avoid relying on unit tests that always pass ... but that do no test the area I'm working on.

Do you write tests while refactoring ?

I usually don't, but I may add new tests in the following circumstances (list not exhaustive) :

  • idea of a new test sparkles in my mind ("what happen if ... ?" - write a test to know)
  • discover hole in the test coverage

it also depends on the refactoring being performed. When extracting a function, I may create a new test if it can be invoked a different way as it was before.


Here are some general advice:

First thing is to maintain a list of the code smells noticed while working on the code. This allows freeing one's mind from the burden of remembering what was seen in the code. Also,

The golden rule is never refactor when the the unit tests do not pass completely.

Refactor when the code is stable, before adding something you know will be impacted by a future refactoring, before to integrate and above all before to say your done.

In the absence of unit tests, you'll have to put the part of code you want to refactor under test. If unit tests are too hard to retrofit, as it usually is the case, then you can create characterization tests, as recommended per Michael Feathers in Working Effectively with Legacy Code. In short they are end-to-end tests that allow you to pin down the current behavior of the code (which is not assumed to be working perfectly all the time).

Don't be afraid to do baby steps. Do not do two things at the same time. If you remark something requiring refactoring, note it down, do not fix it right now, even if it seem very easy.

Check in very often, when the tests pass. So that you can revert a bad refactoring without losing what was done before.

Keep on mind refactoring does not add value to your customer (this can be discussed), but the customer does not pay you to refactor. One rule of thumb is to refactor prior making changes or adding new capabilities to the code.

like image 30
philant Avatar answered Nov 12 '22 14:11

philant


Read Martin Fowler's book "Refactoring"

BTW - that's Martin Fowler's own Amazon exec link, if you're wondering :)

like image 29
MarkJ Avatar answered Nov 12 '22 14:11

MarkJ