views:

353

answers:

18

My question vaguely relates to this one. However, it doesn't address the techniques or practices.

I am reading The Pragmatic Programmer and it strongly advocates refactoring code as often as you can. However, it doesn't go into detail about how to do that and how often. How do you guys go about refactoring your code, and how often do you refactor?

+1  A: 

Generally, I refactor code when I am working on enhancing part of the system, and I know that portion of code that i am refactoring is going to be tested.

If i see something that I know needs to be worked on, and it's not part of the current release, I leave it alone for the moment and get it slotted for the next release. This isn't a big deal for us here, because we do release about once a month, so bad code we spot can wait a little bit (providing it isn't causing a problem in production) until we can get time to throughly review what needs to be done.

Kevin
+5  A: 

Its kind of like cleaning a house, you ought to pick up every day and do the little tasks that need to be done to keep things clean. Then (once a week or so) you take several hours and give the house a good cleaning from top to bottom. Finally (once a year or so) you do a good Spring-cleaning, haul out all the junk and start fresh.

Refactoring is about keeping a clean code-base and it is a perpetual tasks that is never finished.

Andrew Hare
A: 

I refactor, whenever I am not developing new code. I also refactor at any point I notice any bottlenecks.

  • Unwrapping slow loops
  • Moving variable definitions to the head of the function.
  • Replacing slower 'prototype' algorithms with proven faster algorithms.
Dmitri Farkov
Without profiling for the real bottlenecks first, the first two measures are worth nothing. And in 99% percent of programs would not make any difference. This, are also mostly performance optimizations, not refactorings as those described in the classic book by Fowler, Beck et al.
foljs
A: 

other than really - really tight situations where you have to get something done now then i always keep an open eye for refactoring as soon as i write something down. There are times when i have spare time that i will try to re-refactor old code in case i missed something.

Konstantinos
+2  A: 

When I write a first pass of code, I usually try not to bog myself down with thinking too far into the future about possible reuse scenarios. Then, as more reuse scenarios come up the further I get into development, the more I refactor my old code to increase its levels of abstraction and reuse.

So really it's an iterative process; the more I go over and use code I already wrote for new purposes, the more I find it necessary to refactor.

Marc W
+9  A: 

When and where needed.

There is no point on refactoring per se, it is a tool to ease further development. Only refactor when you will get advantage out of it. A small library that will never evolve and is tested is the perfect candidate not to refactor, any time invested on the refactoring will not pay back. Parts of your system/program that will evolve, need maintenance and are hard to read are the clear candidates to refactor.

Always think on the ROI (return of investment), if you start refactoring everything that you now think could be better then tomorrow you will refactor again, and maybe some time you will get time to actually perform some real advance.

David Rodríguez - dribeas
+1 couldn't have said it better. also, avoiding unnecessary "code churn for churn's sake" is a key to stable builds
RobS
+1  A: 

I look for refactoring opportunities whenever I add new functionality or especially when changing existing functionality

ennuikiller
A: 

I refactor very often. The classic scenario is when I end writing big methods and I like to break them apart into smaller pieces. There are many others and they happens with some frequency. Refactoring helps me a lot to keep a balance between coding fast, but keeping my code as tidy as I can.

Rui Craveiro
+4  A: 

I refactor only when I have the code covered by test cases.

Kai Wang
A: 

I think there are multiple deciding factors to refactor code. Some of them can be aesthetics, common functionality, or business process.

For example, I am currently working on the refactoring out of common functionality from several of our utilities (Java Swing). Every utility has the same menu bar across the top. But if I need to add a menu item, I need to do it for all of utilities (copy/paste). So I created a menu bar object and have each utility just uses this object. Now if I add a menu item, they all are updated at once.

The development of said utilities are now going to be done at different locations around the world instead of just by me. So what I am trying to do is break out even more commonality so that when a new developer works on a utility, they can just focus on the meat-and-potatoes and now about the Swing aspect of it.

I have also refactored out several data validation and data insertion procedures into smaller ones. This helps break up the business logic in the application and can help "zone in" right to where you need to go. For example, there is a step in an application that determines if a row can be inserted into the database. Instead of making this one step, I made this about 10, which includes reading the data, validating the proper size and data type, what do I display in the label, etc. Now it is easier to change the business logic of a particular section.

Ascalonian
+2  A: 

Whenever I see code duplicated.

Whenever I see an opportunity for a simpler algorithm/heuristic.

Less and less the closer I get to a release :)

I love tools that help you analyze your code base, and can tell you about unused members, unnecessary visibility (public vs. protected vs. internal vs. private, etc)

I'm working primarily in .NET and ReSharper is Awesome for doing this as well as automating many types of refactoring operation. I think that there are similar tools for many other languages.

John Weldon
A: 

Every time I push -- otherwise my coworkers get on my case, as well they should.

(This is another benefit of DVCS: I can commit correct-but-incorrectly-factored code without pushing.)

Ken
A: 

All the time. Whenever I see a better name for a method or variable, whenever I see something that ought to be inlined or extracted, etc. I rely heavily on Eclipse's automated refactorings to make these changes safely. Bigger, non-automated refactorings happen less frequently, but again when I see the need for them, and only with solid test coverage.

Carl Manaster
A: 

Specific to VS 2008 and C#

All the time. I tend to code with StyleCop and Code Analysis permanently running. Even Resharper is used, and if I see red anywhere, it is time to refactor. Granted I only use these tools to simplify doing it and to force me to do it.

However as I rule I only refactor my own code and new code. Legacy code and code written by others go untouched until instructed to do so.

Diago
A: 

There are levels and levels of refactoring.

I constantly refactor to remove duplication. I don't go looking for duplication, but if I see it, I fix it. I'm constantly using Extract Method to make methods smaller, and following all ReSharper suggestions or warnings (I configure ReSharper to make anything I'm likely to ignore into a Hint). This is also a benefit because you get used to seeing the nice cheerful green square at the top, telling you all is good. When it's a different color, you know something's wrong.

Larger refactorings (the kind the OP may be concerned about), I largely treat like I would a new feature. I'll try to get consensus on how important it is, and will schedule it accordingly. I will not make such a change unless the code involved has a high degree of unit test coverage. "If it's not tested, then it's broken" is one corollary to Murphy's Law. Also, if it's already broken, then I'm not going to make it worse by refactoring poorly-covered code.

I also do not refactor to make the code fit some pattern, or to be more easily modified for the future. When the future arrives, then it will arrive with some failing unit tests that won't succeed unless I make the changes. If there are no such tests, then I can't tell if my changes broke anything, so I won't refactor.

John Saunders
A: 

There are a number of adages and rules of thumb about refactoring. A common one that came immediately to mind was The Rule of Three

In professional life, we obviously have less flexibility about when refactoring can be done than we do in our personal projects. Since changes introduce risk and create work for testers (even if you have all of your regression tests automated, a change moving to production generates some amount of work for a human somewhere in your process besides the human that changed the code), you have to compute the cost to benefit ratio when deciding what and when to refactor.

Here are a few things that I keep in mind when deciding what and how to refactor, especially when I'm working on code that will go to production:

  1. What is the intended benefit of the refactoring? Performance? Decreased complexity? Re-use?
  2. What's the level of impact of the change? High impact changes tend to have a larger amount of testing associated with them and introduce a higher amount of risk.
  3. Can the refactoring be executed cleanly? An incomplete refactoring can introduce more entropy than it takes away. For example, you have some methods that would make a great utility class. If you introduce the utility class, will it be possible to replace all the existing (and potentially copy-and-pasted) methods with calls to the utility class? Is there another existing utility class with similar functionality?
Paul Morie
A: 

The main thing is never tell your boss/client that you're refactoring. Always include the refactoring in with the normal stream of work. It's not worth the constant aggravation of explaining why it's worth paying for.

David Plumpton
A: 

I'm not a big fan of refactoring just for refactoring sake. I always try to keep the code as clean as possible, avoid shortcuts and do it rigth the first time. Each time I add a new feature I refactor on the go if needed, and consider that a part of the feature implementation.

If you can afford to work that way, big and "scary" refactorings are not needed as often as if you don't do regular minor cleanups.

Of course, when scope of the project changes the refactoring is often needed regardless of the shape in which the code is, but the leaner the code is the refactoring is easyer and faster.

Dev er dev