The problem is not technical. It's a question of craft, and social environment.
Refactoring is difficult work.
You have to fix a bug in a giant class. It would be much easier to make the bug fix if the class were split up into several smaller classes, some of the methods were decomposed into smaller ones, if the class delegated to a proxy for certain policy decisions, and if all of the cascading type-based if statements were rolled into methods in the class hierarchy or a Visitor class. But that would take time, work, thought, debugging, retesting, more debugging... IfItIsWorkingDontChange
. Arguably, the refactoring wouldn't be so difficult now if you had been doing smaller refactorings all along, but it's too late for that now.
Refactoring is different.
Most shops need to get the next features and bug fixes out the door quickly, for the next release. How can you convince your management -- or yourself, for that matter -- to take some time to refactor when there are so many important
things that need to be done? However, sometimes refactoring is exactly the right thing to do when you are in a crunch, because it will make the actual fixes easier. But this is counterintuitive, and many don't buy that idea because it's too... well, different
Refactoring is politically tricky work.
See the above for why refactoring doesn't often sit well with management. Other contributions?
People do not know what well written code looks like.
Refactoring is difficult because many, if not most, programmers do not know what the end result should be. They have really never seen well written code and have been taught since writing their first line of code that if it compiles and runs, that is enough.
Refactoring is unnecessary.
In each moment, that is true, but the TechnicalDebt accumulates and may overwhelm. This is much like financial debt. In any month, making the minimum payment on a credit card is not that bad a thing to do, but, over the years it can drain one financially.
I have noticed, however, that in every project I have ever worked on, programmers seem compelled to rewrite the existing software, although usually in an unstructured manner. Refactoring is useful in that it provides guidance on this common practice.
Refactoring is too risky without RegressionTests
that provide adequate functional and code coverage. Of course, the question now becomes WhyNotEnoughRegressionTestsExist?
See also: WhyNotEnoughEditingHappens AlgorMorphics