views:

311

answers:

9

Question

My question is how can you teach the methods and importance of tidying-up and refactoring code?

Background

I was recently working on a code review for a colleague. They had made some modifications to a long-gone colleagues work. During the new changes, my colleague had tried to refactor items but gave up as soon as they hit a crash or some other problem (rather than chasing the rabbit down the hole to find the root of the issue) and so reimplemented the problem code and built more on top of that. This left the code in a tangle of workarounds and magic numbers, so I sat down with them to go through refactoring it.

I tried to explain how I was identifying the places we could refactor and how each refactoring can often highlight new areas. For example, there were two variables that stored the same information - why? I guessed it was a workaround for a bigger issue so I took out one variable and chased the rabbit down the hole, discovering other problems as we went. This eventually led to finding a problem where we were looping over the same things several times. This was due in no small part to the use of arrays of magic number sizes that obfuscated what was being done - fixing the initial "double-variable" problem led to this discovery (and others).

As I went on this refactoring journey with my colleague, it was evident that she wasn't always able to grasp why we made certain changes and how we could be sure the new functionality matched the original, so I took the time to explain and prove each change by comparing with earlier versions and stepping through the changes on paper. I also explained, through examples, how to tell if a refactoring choice was a bad idea, when to choose comments instead of code changes, and how to select good variable names.

I felt that the process of sitting together to do this was worthwhile for both myself (I got to learn a bit more about how best to explain things to others) and my colleague (they got to understand more of our code and our coding practices) but, the experience led me to wonder if there was a better way to teach the refactoring process.

...and finally...

I understand that what does or does not need refactoring, and how to refactor it are very subjective so I want to steer clear of that discussion, but I am interested to learn how others would tackle the challenge of teaching this important skill, and if others here have had similar experiences and what they learned from them (either as the teacher or the student).

+2  A: 

I am not 100% to understand your question but I think you can refer yourself to Code Smell that need to be refactored.It contain a lot of example that you could show to other.

Here is a list of when refactoring should be used (list of code smell)

Daok
This is certainly useful, but I'm not convinced it's the best way of teaching someone the concepts and skills required when refactoring.
Jeff Yates
At my University (Canada) it was the way they show us why refactoring is important and how to develop ability with by comparing to those smells.
Daok
Yes. It's an important part of learning refactoring (hence the up vote).
Jeff Yates
+1  A: 

Pair Programming seems to be the best way for me to get this across. This way, as we're working on real, production code, and we both encounter some code that doesn't smell right, we tackle a code refactoring together. The pair acts as the driver's conscience saying to do the right thing instead of the quick fix, and in turn, they both learn what good code looks like in the process.

Refactoring can be an art, and just takes practice. The more you do it, the better you get at it. Keep studying the methods described in Martin Fowler's Ractoring book, and use your tools (Resharper for Visual Studio folk)

casademora
This approach was certainly helpful last night. I don't think the project lead will authorise it as an ongoing approach to our work but I'm inclined to use it again in similar circumstances.
Jeff Yates
+2  A: 

If you haven't read it, Martin Fowler has an excellent book on the subject called Refactoring: Improving the Design of Existing Code. He goes into substantial detail about how and why a specific piece of code should be refactored.

I hesitated to even mention it for fear that knowledge of this book is assumed by someone asking about refactoring, and that you would think, "Duh, I meant besides the Fowler book." But what the hey, there you go. :-)

Brian Sullivan
Thanks, I know about the book. Like I said, I don't want to discuss what should be refactored and why, I want to discuss how you teach someone that. The book certainly helps, but I think there are other methods.
Jeff Yates
+2  A: 

You don't mention tests. To 'prove' that a refactoring does not break the existing functionality you need to either have existing tests or write tests before doing the refactoring.

Paul Croarkin
Yes, I understand that testing is important when refactoring, but I want to teach someone the importance of refactoring and how to do it. While tests are an element of refactoring, they aren't necessarily how you teach it.
Jeff Yates
+1  A: 

Like most programming, refactoring skill comes with practice and experience. It would be nice to think it can be taught, but it has to be learned - and there is a significant difference in the amount of learning that can be accomplished in different environments.

To answer your question, you can teach refactoring methods and good design in a pedagogical fashion, and that's fine. But, ultimately, you and I both know attaining a certain level is only through long hard experience.

Cade Roux
So true. Experience is certainly a factor. A colleague of mine also believes there's an element of talent involved and that some are "born to refactor".
Jeff Yates
Amen to that, brother.
Cade Roux
+1  A: 

One simple way to conceive of refactoring is right there in the name -- it's just like when you factor a common variable out of an equation:

xy + xz

becomes

x(y + z)

The x has been factored out. Refactoring code is the same thing, in that you're finding duplicate code or logic and factoring it out.

dirtside
Thanks. That's a great way of explaining what refactoring is doing, but it doesn't go so far as to teach the actions of refactoring and the practices therein.
Jeff Yates
I would edit this answer so that it used `•`.
Brad Gilbert
+1  A: 

It sounds like your approach is a very good one. At the end of the process, you showed how you were able to uncover and fix a lot of problems. For educational purposes, it could then be interesting to invent a new change/enhancement/fix. You could then ask your mentoree how they would enact that change with the old a new codebase. Hopefully they'll see that it's much easier to make the new change with the refactored code (or how doing more refactoring would be the easiest way to prepare for the hypothetical change).

Mr Fooz
+1  A: 

I see a couple of different ways you could try to teach refactoring:

Given textbook-like examples. A downside here is that you may have contrived or simplistic examples where why refactoring is useful doesn't necessarily shine through as well as in other cases.

Refactoring existing code. In this case you could take existing legacy code that you'd clean up, or your own code in development and show the before and after doing various bits to see how much better the after is, in terms of readability and ease of maintanence. This may be a better exercise to do as this is live code being improved and enhanced to some extent.

It isn't something that someone can pick up instantly, it takes time, practice, effort and patience as some refactorings may be done for personal preference rather than because the code runs optimally one way or another.

JB King
+1  A: 

Teaching someone to refactor when they aren't a natural is a tough job. In my experience your best bet is to sit down with them in an office and refactor some code. While you are doing this keep up a "stream of consciousness" dialog. Talk about what you see, why the code doesn't smell right, options to refactor to, etc. Also you should make sure they're doing the same thing. The most important thing is to impart why, not how, to change the code. Any decent programmer can make a change and have it work, but it takes skill and experience to be able to state why the new solution is better than the previous.

Bryan Anderson