Thoughts on Project Refactoring
Finally I have convinced my team and management (!), that the project we have needs at least some refactoring. Actually I was lucky – they did not have a choise and I didn’t need to convince them too much — new implementation for Travelling Salesperson Problem is vital and doing it the way we planned and getting away without rewriting some of the classes is impossible or at least close to it.
I consider myself lucky, as convincing management is a tough job, for example, see this thread on Stackoverflow or one on Programmers SE. The rewriting of the code would have been delayed for ages if it wasn’t for the TSP task.
For the task, I have been consulting newly discovered book Object-Oriented Reengineering Patterns. It gives some practices on reengineering the project and it’s good to know that I was unknowingly fallowing them on my own. Of course I cannot write everything in one blog post, so you should really better read a book, however I think I have some stuff to say and I will use quotes from the book, and will share one with you right away:
…the most interesting and challenging side of software engineering may not be building brand new software systems, but rejuvenating existing ones.
I have picked this quote up because I’ve came across a lot of software developers who were surprised that I actually wanted to do the refactoring. They insisted that reengineering code of someone else is dull and boring. But I must disagree — it is more challenging and therefore more satisfying when completed, and at some points even more interesting. Also I must say, that I love developers that want to redesign the software they are working on. It is a quite challenging task and it shows that these developers do care about the work they do, quality of the software and maybe even future developers that are going to work with the code they struggle with now.
On the other hand, I understand managers who does not want refactoring in any way. There are no hard evidence that what you are doing is going to give returning value other than feeling good about the work you’ve done. The time spent on redesing might never pay up and it is hard to measure too.
They didn’t know what they were doing
So why do we complain about others code so much? Weren’t the guys writing it sure of what they were up to? In fact they were not: while working in CERN I was in a workshop for anti-patterns. The presenter gave me one of the best software maintanance advises I have ever had – “They didn’t know what they were doing”.
What do you do when you come across piece of code that seems weird, ugly and you have a very small idea what it actually does? For some time I was just in the mood of “ah, they knew what they were doing”. But that is terribly wrong. Read it, understand it and then fix it or make it more readable for others. Huge chances are, they really didn’t know what they were doing. If they were, what are all of those bugs doing in your software? If the piece of code didn’t cause a bug so far, it doesn’t mean it will not eventually, and at that time it might be critical, right before the eyes of a important client during presentation.
Rewrite from scratch vs refactoring
Writing something new is always pleasant. You take of clean, there is no code smell and everything seems right this time, every piece of code commited is sparkling clean.
On the other hand refactoring requires you to read code others wrote. This is hard and unpleasant. You need to read some of the ugliest parts when the only thing coming to your mind is “WTF were they thinking!? What is this shit?!”.
But are you sure you can make a better job? Are you aware of all the bugs that were fixed in the legacy system? You can use TDD and write tests for all the bugs registered on bug tracking system, but how many of them were not registered? For example ones fixed during code reviews. Are you sure you will not introduce new ones? If done not right, the fresh and new project might very well become a burden as well. While performance, design and almost anything else could have been fixed in the system that is no more ugly than the new one and it all could have been done in more reasonable time.
In many cases code becomes ugly over time because of all the weird bug fixes:
The only reason that there were problems with the legacy code was that the requirements had changed since the original system was designed and deployed. Systems that had been adapted many times to changing requirements suffered from design drift.
If you think code is ugly and should just be thrown away and rewriten, think again.
You don’t need huge refactoring projects to make your system clearer, you can take care of it (and should) by daily work when fixing some weird piece of code or during code review. Everything with small daily refactoring.
Refactoring or Refucking?
Lets say you are given a task to make some changes in part of code you didn’t write. Most probably you’d be like “The fuck is this? The fuck was that?” “This is piece of crap. I would have done better job.” Everyone thinks themselves to be above average, for example few years back, due to the lack of pattern knowledge and quite shallow understanding of polymorphism, I would consider code I write now hardly readable. Are you sure you have enough knowledge in patterns, anti-patterns and understanding of the product you are going to refactor? Just because code seems hard to understand for you, it doesn’t mean anything. In fact, there might be nothing wrong with code and maybe there are some problems with you.
So don’t do premature optimizations, first find root of the problem. Maybe it is wrongly used container and not iterator vs enumerator problem.
Don’t brake patterns and programming paradigms you don’t understand or don’t like. Don’t do too general implementations if you think that in future you might need something. Keep it simple and remember, that some patterns work best in one situation, others work best in other. The right usage of them is the true skill, not the knowledge of them all and choosing the most general all the time.
Most of refucktoring I’ve seen (and done myself few years back) is when software developers move to new programming language and when they need to implement some changes in one method, before doing something, they rewrite it in the manner of their better known language! Please don’t do this. As I’ve mentioned in my previous post, it is normal to write in style of the better known language while you are learning, but it is not normal to think it is better!
I will be doing knowledge sharing seminar in my workplace in few weeks time and hopefully publish some posts about the redesign of software itself.