thank you for the opportunity of discussing such an interesting book and topic, I have the following questions based on the current situation/plan at work.
basically we are maintaining a legacy software/framework, and I encounter lots of situations where refactoring/rewriting is required, however the scope of impact for any change is hard to measure/find out since our technology is outdated, what can we do in case we don't have an automated build/deployment/integration framework to support testing and finding any problems if any.
another question I got is that since we are using an outdated technology, migrating to newer technology is always an option and soon-to-be a project, however I'd like to hear your thoughts on combining refactoring and migration at the same step if possible, or how to address these two topics in general. what would you recommend in such a situation.
While automated builds and deployments are great for productivity, they are not necessary for you to start writing unit tests and refactoring. The biggest obstacles to refactoring, IMO, are management's willingness to let developers do the right thing on one hand and developers' ability and skill to do the right thing on the other hand. Refactoring is not easy and it requires experience, insight, and know-how to do successfully. Chris gives some good advice in his book: consider value, risk, and difficulty when deciding to make major changes in your codebase, make large changes incrementally, separating refactoring from other work.
In my own work, I hardly ever ask permission to refactor code. First of all, refactoring is my business as a developer. Users don't care if the code is a mess as long as they can get their jobs done. As a developer, however, poorly written/designed code impedes my ability to do my job. So, it is incumbent on me to do what I can to keep myself productive and refactoring is one of those things.
Second, I keep my refactoring efforts small and limited to three refactoring: Rename, Extract, and Composed Method. This is usually enough to get me to a point where I'm not scratching my head in confusion or fantasizing about finding the original developer and making his life as miserable as he made mine with his code.
Of course when the refactoring effort extends beyond what's needed to make the immediate code that I'm working in more coherent and cohesive, then I'll discuss the issues and options with the stakeholders. At the very least, discussing issues and options with the stakeholders gets everyone on the same page with regard to the state of the application and how valuable/important certain parts of the application are to the stakeholders. Usually, the more valuable/important some piece of functionality is, the easier it is to justify spending time & effort to refactor the parts of the application that support that functionality.
I work on a legacy app that's undergoing technology migration.
It's interesting (and case specific) when the choice is made to
- write tests and refactor
- rewrite / rearchitect / test
- try not to touch too much but still get to technology goals. Write as many tests as possible.
Mostly all this has to do with risk / time / money / difficulty - like Junilu said.
Getting repeatable / reusable / readable tests is a big concern because one day if the decision is made to do another thing, you want to be able to understand what effort was put in so far -- and how things work!
When you do things right, people won't be sure you've done anything at all.