As new words and concepts diffuse in to wider use, their definitions become simpler or broaden to cover more scope. Like the kid’s telephone game, each time the concept is passed to another developer, the information gets a little more muddled. In software development, declaration, macros, syntax and other programming constructs have to be exact or the compilers will fail. Yet, when developers discuss concepts about programming, most of the time, that precision of language is lost.
The telephone game seems to have happened to refactoring. I subscribe to what would be consider the “classic” definition of refactoring: the process of optimizing or extending a class but leaving the existing exposed interface alone. It seems that refactoring has been generalized from that definition into covering all activities related to touching old code. Even worse, it has become an excuse to rework someone else’s code and then bitch about how bad it was. Just look at the twitter stream for refactoring for a never-ending torrent of abuse.
There is one simple way to tell if your efforts are truly a refactoring or not. Did you break any of the unit tests? If you did, then you are rewriting code instead of refactoring it and you had better update all the test cases while you’re at it. Don’t get me wrong, there are times to rewrite software, but they are few and far between and, in my experience, it almost never pays off.
Refactoring isn’t just a nice philosophical idea; it supports one the most basic concepts in software development–backwards compatibility. If you want to keep your customers and enjoy that paycheck, don’t break features or APIs in products without good reason or get buy-in before release day.
To refactor the medical phrase “First, do no harm“, for developers it should be “First, break no test”.