14

Given a small project that aims to add new functionality to application, the changes introduced touch some existing code, involving updating these in certain areas. During implementation, I've found some of these code which were updated have candidates for refactoring.

Is this an appropriate time to refactor which in turn would require regression testing for those components affected (thus possibly introducing scope not originally part of the project)? Or should I defer, complete the functionality and perhaps have a separate project for refactoring (although I'm a bit hesitant as business users might not fully sponsor a project that does not add any functionality, unless they value code maintainability...)?

Robert Harvey
  • 198,589
  • 55
  • 464
  • 673
  • 3
    Do you have the tests in place allowing you to do the wanted refactoring? –  Sep 07 '11 at 12:48
  • 3
    You answered it for yourself, the clients aren't going to care about code maintainability unless the code itself is a deliverable. They care about money and time and assume quality as a given. Quality, time and cost are directly related to technical debt but they are also relative to what they are willing to accept. If you DON'T incorporate refactoring as you go then code maintainability will degrade and technical debt will skyrocket unabated. – maple_shaft Sep 07 '11 at 14:11

5 Answers5

19

Absolutely.

Refactoring should be done on a working and "passing" project. When all your tests (at the unit, system, and acceptance levels) pass, you know that your product meets requirements. When you refactor, you can continue to confirm that all tests continue to pass. If any test begins to fail, then you did something wrong and need to correct it. If you have failing tests, you should correct those before refactoring so you can always ensure your refactoring isn't changing the functionality of the system.

This is also a perfect time for refactoring, assuming you have the time and resources to carry out the refactoring and still deliver on time and budget. Refactoring now will make it easier to understand and maintain your system, so as you add even more new features, it becomes easier. You need to fight against code rot and software entropy.

As Joel Etherton points out in the comments, you need to manage the scope of refactoring. Focus on refactoring the parts of the system that you will soon be adding features to, performing refactorings that will make it easier to work with or add the new features. The use of static analysis, metrics tools, and code reviews can help you identify areas that are most critical. You don't want to miss deadlines because you were refactoring - you still need to continue to add value to the customer.

You mention the customer not seeing value in refactoring. Typically, the customer doesn't care about the quality of the code, but of the product. Refactoring will make it easier for you to maintain a high product quality and keep delivering a product that meets the changing needs of the customer. Try to negotiate time to refactoring into your schedule (customer wants X features in Y days, try to see if you can't get Y+Z days or X-N features so you can spend time on design, refactoring, and implementation), if you can.

Thomas Owens
  • 79,623
  • 18
  • 192
  • 283
  • 1
    +1 especially for the paragraph about the value of refactoring for clients. – Marjan Venema Sep 07 '11 at 13:00
  • 1
    Assuming you have a good set of unit tests to validate the refactoring does not change the observed behavior. Given the choice of refactroring or unit tests. Add unit tests first. – Martin York Sep 07 '11 at 13:40
  • 7
    @Thomas Owens: +1 I agree, but I would also add a note of caution on refactoring. It's very easy for refactoring to start a cascade of refactoring that can bloat the actual work necessary and cause deadlines to zoom by. – Joel Etherton Sep 07 '11 at 13:42
  • @Joel That's a good point. You do need to keep refactoring limited in scope to make deadlines. – Thomas Owens Sep 07 '11 at 13:48
4

Refactor soon, refactor often.

If you can afford it (time, money, etc.) you should do it.

I say this because sometimes you may run out of time, or like you say not getting money for a code maintenance intervent, or you want to complete your project as soon as possible, and more in general because refactoring needs resources. But apart from that it's always a good time for refactoring.

You want an up-to-date code, and if you feel that your code actually needs some changes, especially when adding new functionalities, then you should change it.

Don't forget with a version control system you can actually fork your project into a new branch, so you won't affect your current code at all.

Jose Faeti
  • 2,815
  • 2
  • 23
  • 30
3

Consider answering the quesitons below, then it would be easy for you to do the decision. The wisdom "don't fix it if it is not broken" is tempting but not always true for professional work.

0-Is there a customer complaint about this code?

1-Is this necessary for the functionality of the application

2-Is the current code harmful?

3-Is the cost of change worth it?

4-Could you afford the cost?

5-Is this the best utilization of your skills to the organization

6-Would your changes require your user to re-install the new change - Could you justify that to the customer?

7-Could you tolerate the risk of a bad fix?

8-Does the change affect other code outside your project?

9-Is this an evolving product or a stable product? If it is evolving could you include the changes with the next release?

NoChance
  • 12,412
  • 1
  • 22
  • 39
2

If the refactoring is needed to implement the new functionality then it should be done and factored in as part of the new development.

Having duplicated code will cost you (both you personally and the company) more in the long run as edits get made to one place and not another.

You do need to have a set of tests - either automated unit tests or regression tests that you can run that prove that you haven't introduced problems to the existing functionality.

If the refactoring is just a "nice to do" - i.e. it's not in code directly affected by the new functionality then I'd leave it alone. You are introducing a change for the sake of change.

ChrisF
  • 38,878
  • 11
  • 125
  • 168
0

It sounds like refactoring the code will make it easier to add the new features; that's the theory. Include this in the scope of the new features. You're more likely to get buy-in from business users this way. In this case, you should be able to make a compeling arguement and justify the time for refactoring. Hopefully they'll understand that this is a necessary part of the development process and will have fewer objections. You may not always be able to demonstrate this direct benefit.

JeffO
  • 36,816
  • 2
  • 57
  • 124