Tuesday, December 9, 2008

Refactoring - small steps is the key

Whenever we do refactoring, we try and make the changes in steps, and steps which are as small as reasonably possible.

Some people when they think of refactoring think of it as if it were a complete mini-rewrite of a part of the code – rip everything out and redo it better. No! No! No! We identify a single clearly defined change which we want to make to the program – like extracting a method or creating a parent class – and we do this change in a series of very small steps, making very small changes to the code, testing after each small change, and we repeat this until the series of small steps is complete and we arrive with our single clearly defined change complete.
The idea is that if we make our change in small steps we are both less likely to actually make mistakes in the process, but also, if we do make a mistake, it is much more likely to be instantly apparent, easily fixable and small.
By contrast, if we make a whole bunch of changes to code all at once, then it is very easy to introduce all sorts of bugs which we would not easily notice when we test.

The idea is to do each refactoring in steps almost so small that even a complete programming dolt would not make a mistake. The fact that I actually do make mistakes when refactoring shows just how essential this is. Or maybe it shows I am a programming dolt? Whatever the real case is, each of us makes mistakes, and the smaller the change, the smaller the chances of making one. Refactoring is not about changing a program in a random ad-hoc manner; it is about changing a program in as disciplined and organised way as possible so that bugs have as little chance as possible to creep in. Taking small steps is a key part of that discipline.

Tuesday, December 2, 2008

Refactoring - One change at a time

When we do software refactoring, we just make one change at a time. Not a whole bunch of little changes, but one single well-defined change. You’re maybe tempted to make a whole bunch of changes at once. No! One I said! One single change! That’s all. I know, you want to change a number of things, but you are only going to change one. But patience: later, maybe only a few minutes later, you will change the next. So you can make a whole bunch of changes, but you simply make them in sequence, one at a time.

So what constitutes a single change? A single change is any individual change which upon completion leaves the code internally in a better state. It can be anything from the renaming of a local variable to something clearer, to a difficult breaking up of a single class into a complete hierarchy of smaller subclasses.

Though I hope it does not need saying, I will say it anyway, by one change at a time I do not mean that the code actually does anything different at the end of the change. No, as you will well remember, refactoring, at the very core of the definition, says that there is absolutely no change in what the program actually does. The code will have absolutely identical functionality at the end of the change as at the start of the change. The change is to the clarity of the code, or the structure of the code, not to the functionality of the code.

For example, if our code was a mathematical equation, it would start perhaps by saying 4+3+7+6 = 20 (is this true or not? Hmmm...who knows – maybe we could refactor it to make it clearer), then after the change it would say 5+5+5+5=20 (ah! That’s clearer! Now I can see how it works!) – the value at the start and the end, the ‘20’ of the result, is the same, so there is no change in the functionality, but what has changed is the way in which it was calculated. Refactoring always keeps the result the same, but changes the way in which it is done to make it clearer. Anyway, I’m sure I didn’t need to tell you that by change, I mean a change that doesn’t change anything, since you remember that part of the story, but I thought I’d remind your slightly less attentive colleague.

See my book The Refactoring Workout for more on refactoring.

Tuesday, November 25, 2008

The Golden Rules for Software Refactoring

How do we actually go about refactoring? Below are the Golden Rules.

  1. One change at a time
  2. Small steps
  3. Test after each step
  4. Frequent builds

These four steps are the key principles which you should keep in mind when doing any refactoring. If you remember nothing else about the technical aspects of refactoring, this is the list to remember. It is the mantra which during refactoring you should continually chant to yourself. It should be one of the post-its pasted to the side of your computer screen. Tie them to your hands as a reminder; write them on the doorposts of your house; wear them on your forehead....OK, now I’m getting a bit carried away.

But they are pretty important stuff. They are the key to good refactoring.
We are only going to make one change at a time, only one clearly defined improvement to the code. This single change we are going to try and do in small steps, often the smallest steps possible. Then we are going to test. If the test goes all right, then we are going to make another single change, again in small steps, and then we are going to test again.

In future posts I plan to look at each of these in more detail.

See my book The Refactoring Workout for more on refactoring.

Tuesday, November 18, 2008

Introduction to causes of software spaghetti

When talking about software refactoring, it's worth stepping back and taking a moment to think about why we need to be worried about our current software processes.

Assuming you have been in programming for any length of time – either directly working on the code or more indirectly in some sort of project management – you will have learnt or developed a certain notion of how you would really like your software to be.

You will want it to be really well structured. Well designed. Well written. Modular. It will have proper separation of each of the different layers of the logic; business logic, application logic, presentation layer. It should be easy to change the software. It should be efficient. Easy to understand, well-documented. In brief, it should ideally be a masterpiece of modern software engineering, an exemplary demonstration of good software. It will demonstrate an internal structure and quality that simply has ‘professional’ written all over it.

And yet, if you have been in programming for a little bit longer, you will know that, somehow, almost for reasons you can’t quite put your finger on, software gradually goes off the rails. No matter how hard you seem to try, your software projects slowly but surely lose this dreamed of structure and clarity and become more and more the spaghetti code which you want to avoid.

Why does this happen? Is there any way to avoid it happening in the future?

These are vital questions.

Maybe you have always inherited existing projects, and they were already in a bad way when you took them on. At least there you can take no blame for the poor state that they are in now, and convince yourself that if only you’d been on the case, since the beginning, they would still be in that really good state which you would like.

Is this realistic, or would it have still gotten in the mess even with you at the helm from the beginning? And what about this software which seems to be already in a poor state, is there any hope for it, or is it really just a question of waiting impatiently for the day where it is rewritten or no longer needed? And even then, if it were ever rewritten, would it really be able to avoid the mistakes of the past? Or are there some negative factors in software development which just cannot be tamed?

You will guess perhaps that my answer to these questions is that there are a number of reasons why software almost always gets in a bad state. In this chapter I really want to take a look at those reasons. I want to examine why software tends almost inexorably to deteriorate. I want to have a look at the causes that push software in a negative direction, and why in many ways we should remain relatively pessimistic about being able to fully control these negative causes.

There are a whole range of causes which work against this dream of beautifully structured, well designed, flexible, well written code. Each one is perfectly natural, and generally unavoidable. Note, I said that these causes are largely unavoidable – there’s very little you can do about them. Indeed, in most software development, they are inevitable.

And each one has a detrimental effect on code quality, on code simplicity, on code flexibility. Each one pushes the code to become more and more disorganised. Each one pushes the code to become more and more complex. And each one pushes the code to be more and more difficult to maintain and enhance.

See my book The Refactoring Workout for more on refactoring.

Tuesday, November 11, 2008

Refactoring - Room of Files analogy summary

In my previous posts I have compared software refactoring to sorting out a Room of Files.

You may think in this example I have been just doing trickery with the numbers. It is true that in practise, with refactoring, the time overall will take longer. Nonetheless, even when the total time for things done with refactoring is longer, there will still be many benefits, both tangible and intangible:

  • The actual time spent on any given file-finding task is objectively reduced. This corresponds to an actual reduction in the time programmers spend on any given programming task (when not counting any new refactoring).
  • It is easier for people to do the required work. It’s a lot easier for a programmer to work on a program which is in a good condition than one which is in a poor condition.
  • When files have to be found with a degree of urgency and speed then the room will be ready. This corresponds both to the need to have programmers fix critical bugs quickly, but also to develop new features to a tight deadline.
  • The chance for duplication and errors are reduced when everything is well-ordered. One of the causes of errors in software is when things are in several places instead of just one; refactoring removes this duplication and such errors naturally get reduced or eliminated.
  • People’s morale will be much higher, as a result of contributing to a tidy and well organised room. Programmers will be much happier working on a program which they are really trying to make a quality product internally, rather than something which is just a hack.
  • People’s morale will be higher, as work will feel fast and efficient, because it is.




So, what are the important messages from this room of files example?

  • Refactoring is not something you typically do in one big blitz, but rather something you integrate as a part of normal work.
  • When considering the cost and benefits of a refactoring, the costs always appear at the time of the refactoring, and the benefits always appear after the refactoring.
  • Even though on the detail level, refactoring takes more time, when looked at from the wider perspective, it can actually save time. Even when there is no overall saving of time, there are other benefits which still make refactoring worthwhile.
  • There are many benefits including: efficiency of working, reduced bugs, faster when needed, improved morale.


See my book The Refactoring Workout for more on refactoring.

Tuesday, November 4, 2008

Refactoring - Room of files analogy (worked example)


In my last post I introduced the idea that software refactoring could be thought of as rather like dealing with a room of files.

Let’s take the Room of Files and work through how that gets tidied up (the full figures are shown in the table below). It is certainly true that this is only an illustration, and the figures have been chosen to come out as particularly favourable to the refactoring side of the story – that I will admit. However, I think as I run through this example with you, you will find it very instructive, because, though we might want to argue about the precise figures, many of the principles are much more incontrovertible. In any case, the likely benefits of any particular refactoring will always have to be judged on its own merits.



Let’s say, for arguments sake, that before the room is tidied it typically takes a day to find a file. Sometimes, when you get lucky, it takes only half-an-hour, sometimes as much as two days, but on average one day. So, one day is our current benchmark for finding files.

When we first go and hunt for a file, rather than spend a day looking for a file, we start by spending two days tidying and organising (=refactoring) the room. Then, we actually do the directly productive work which we set out to do – finding the file. Of course, the room is now already in a much better state than it was before we tidied it, so it might take us, say, 6 hours rather than the typical eight to find it. Nonetheless, rather than take just 8 hours to find the file, we have taken a total of 22 hours.

The next time we go and look for a file, rather than spend time directly looking, we first spend (say) another 6 hours tidying and organising the room. By now the room is really starting to improve. When we have finished tidying, then we actually do the directly productive work we set out to do – find the file. This time, rather than the already improved 6 hours, it is likely to take much less, say 4 hours. Nonetheless, yet again, the actual amount of time we have spent in total (6 hours of refactoring and 4 hours to find the file) is more than we might have spent if we simply came and looked for the file (8 hours). You will see however, that even if we leave the room in its current ‘partially refactored’ state, things have improved significantly over our initial situation. Now, each time we wish to find a file, even if we don’t spend any more time tidying, a file will typically take only 4 hours to find every time. The savings we have gained in terms of the vastly improved speed of finding a file, are paid for once, but benefit us each time we revisit the room.

This is exactly how it is with refactoring code. Whenever we improve the clarity of the code, and thus the speed at which future people can understand and change the code, the benefits of any improvement apply for every future occasion on which that code is worked on.

The next row of imaginary figures is very interesting. Here, on the 3rd visit, we actually spend 3 hours for refactoring, and 3 hours for finding our file. What is interesting is this: we could find our file now in an average of 4 hours, but yet we choose still to spend just as much time tidying before we look for the file, and, even with that being the case, we have still taken less time in total (6 hours) than in the scenario where we never do refactoring of the room (i.e. 8 hours).
Think about that for a moment. In coding terms, it is as if we have decided to spend just as long on refactoring as we will on the ‘actual’ coding, and yet, and here is the marvel of it – we have actually spent less time in total than we would have done under the scenario of not ever refactoring. We have spent twice as much time as we needed to get the job done (6 hours – 3 refactoring, and 3 finding the file), and yet we have still spent less time in total than the poor person who is working on the unrefactored room (8 hours).

I can imagine many of you now scurrying to the tables of figures trying to understand fully this apparent cloak-and-mirrors trickery, to try and understand the error of the logic.

There is no error in the logic. The apparent deception comes from the fact that the benefit of a refactoring is seen after the refactoring has been done, and this current visit to the room of files is really reaping the benefits of all previous times we have spent tidying the room.

What it does illustrate is that in order to understand the benefits of refactoring, we can never consider a single refactoring in isolation. Almost any refactoring when looked at in isolation will probably not be worthwhile – sometimes it happens that the time spent in refactoring is immediately repaid in the speed of making the change we want, but this is usually the exception rather than the rule. No, the real gains usually come later, in all subsequent changes.

Imagine trying to get managerial support for a particular change where you want to spend two days doing it rather than a few hours – because you “want to do some refactoring you think is needed”. It is difficult. Support for refactoring must be won first in a global discussion of its advantages when looked at in the global context rather than in a specific debate about a single refactoring, since any refactoring in itself, generally does not look worth doing, but it only becomes valuable when we think of the many times in future that the code will be worked on.
Let us skip in the table to the 7th visit to the room. Here you will notice that 1 hour is spent refactoring, and 1/10th of that in actually finding the file. What profligacy! Ten times as much time spent refactoring as actually doing the work? Of course we could never agree to that! You, my now learned reader will already see the fallacy of such a claim. You will know that refactoring, even at ten times the time spent on the ‘actual’ work, will soon enough reap its rewards.

From the 8th to the 11th visit I have shown no refactoring at all. There comes a point where there is little to be gained from further refactoring.

The other thing to note on these visits is the difference in time to perform our required task of finding a file: 0.1 hours versus 8 hours in the still untidy room, a factor of 80 times quicker. Is this realistic? Certainly I think for the room of files you can see that this would be perfectly reasonable; if you have a room of files in complete and total disorder it could easily take a whole day to find something, but yet, if the room was beautifully and logically arranged a file could almost instantly be found.

But what of our software? Can it really be that bad? Yes, I think the ratio sometimes is that bad. Yes, I do think that with badly decayed software, things can even take as long as 100 times as long! You can and understand it clearly with a very simplified example like this room of files, but the reality is that it is often time-sappingly bad within poor code too.

This huge amount of extra time needed to work on our software can apply from the smallest change to the largest. A bug will take several days to find and fix, rather than ten minutes (that’s a factor of 100 as near as makes no difference). A major change will take man-years rather than man-months.

On the 12th visit I have shown a little blip in the hours spent refactoring column. In the previous visits, no time at all was spent in refactoring and here, all of a sudden, another half-hour is spent in refactoring, without any apparent gain in subsequent times finding a file. Sometimes refactoring will be like this, that there are no immediate obvious gains in time. But any refactoring will be done because the person doing it perceives it as something useful for bringing more order to the situation. Perhaps they didn’t think of a way to improve things before; that’s fine, there are usually many visits to the same piece of code, and at each stage there is the opportunity to make improvements which suddenly become apparent, even if they hadn’t been thought of before.

Let us now look at the total time spent over all the iterations. When we look at the totals, for the refactoring scenario, we have actually spent twice as much time refactoring the room (30.5 hours) as we have actually finding a file (17.2 hours). But yet, when we compare the overall totals for working with the room in the two ways – a room of files with refactoring, and a room of files not refactored – the overall time where the room was treated with refactoring (47.7 hours) is half that where the room was not refactored (104 hours).

See my book The Refactoring Workout for more on refactoring.

Tuesday, October 28, 2008

Refactoring - Room of Files analogy


To help understand software refactoring, I want to introduce an analogy of a Room of Files.

Imagine you have a large room full of files, but which is a real mess. It has dozens and dozens of filing cabinets, and shelves, with hundreds and hundreds of paper files. And regularly, this is where you come to get your different files. But it’s a mess. A real nightmare to find what you want. Sure, there is some order within it. But the chaos is so bad, that...well, the order that there is within it...is very difficult, if not impossible, to spot.

That’s often what our software is like! Our software has some sort of order, but the disorder that has gradually accumulated has more and more taken over, until it becomes almost impossible to see the order through all the disorder.

Now imagine that you regularly have to come into this room and find a file or some papers that are needed. How easy is it? How much time does it take? It takes ages just to find where the thing is your looking for. Doesn’t that describe accurately how things are like in our software? Doesn’t that describe how often it takes to understand all the parts that are causing the latest bug? Oh, you think that things are different in your software! Are you sure? How long does it take you to track down bugs? How often do functions get rewritten in different places with different names...just because people didn’t realise they already existed. Somewhere in the code. Somewhere the programmer just didn’t know about.

I have too often worked on code where I have almost wanted to cry because something which should be just so simple...is just so difficult. Tracking down and finding a relatively simple bug can take a day or more, when really it should only take half an hour...or less. Why? Because the code is in such disorder.
And as for adding new functionality, adding new functionality to code in such a state can be nearly impossible.

It’s a thing difficult to objectively prove, but when I work on code which is really bad, I get the feeling that programming tasks take something like 10 times as long as if the code were in a good state. Yes, 10 times as long. Because the poorly structured code just makes it like that. A task which should take half an hour takes a day – that is 16 times as long by my reckoning.

Think of the Room of Files. If the room was extremely well-organised, how long would it take to find a file you wanted? A few seconds? Five or ten minutes max? And what about with the room in a really messed up state? A couple of hours? All day? Maybe you wouldn’t even find it after a day because you missed it first time through, and would have to go through everything all again, but this time a lot more carefully and slowly.

And that’s often what our software is like. A job which should only take a short time takes not just twice as long, but easily five or ten times as long.
Sometimes people see refactoring as a waste of time. The train of though has a certain logic to it. It goes like this. If I fix this bug, or add this new function, it will take me a certain amount of time, say one day. If I do refactoring as part of the task, the task will take me twice as long. Twice as long! You can imagine the non-understanding manager making you feel like you’ve asked to go on four weeks holiday just when the project is struggling to hit its deadline: What on earth would you want to waste your time like that!? You can do it in a day, but you’re going to take two days to do it...why, because you want to do some refactoring?! And what will be the benefit to the customer of this refactoring? The code is a little bit prettier inside!?!

I think refactoring, done properly, will typically mean that coding will (in the microscopic view of things) typically take twice as long. Why? Because you will be continually finding ways to improve the code. But note well, I said in the microscopic view of things, that is, when we look at a single isolated task. Indeed, in a way, it typically has to be the case that when you look at a single isolated task, doing some refactoring will make the task take longer. Why? Because almost by the definition of refactoring, the benefit will come when people work on this code afterwards. Yet that future may even be directly afterwards. I have said elsewhere that you don’t do refactoring if you are the last one to ever be touching a piece of code. But in the macroscopic view of things, when you look at the overall productivity of the programmer, it increases significantly. The programmer easily becomes say twice as productive, but more probably tasks can be done five or ten times as quickly or even quicker.

Refactoring code is like tidying up in the Room of Files. Sure, if I just search through the mess of files for what I’m looking for, it’ll take me a certain amount of time (a day say), and if I also spend time doing some tidying up it might take me twice as long (two days say) in total to find the file I’m looking for, but the room will be a bit more organised. Sure, I’ve lost time on this first search. But, even if I haven’t completely sorted out the room, I’ve gained loads of time on the next search.

And notice how I refactor (tidy and organise) the Room of Files. I don’t set aside a week or two, or even a month or two if needed, to really sort it out. I could. But in general there will not be the management support for that sort of full-time clear-up, even if that were the best way to do it.

Some people mistakenly think that because you adopt a policy of refactoring, you are going to be spending weeks on tasks which previously would have taken a day. That is not usually how one approaches refactoring.
What we do is at the time of actually doing some needed work (looking for a file in the example, fixing a bug or adding some new feature in software), we spend a proportion of our time in improving the ability to do our job in all future visits.

In fact even if there were the possibility to do a full-time clear-up, there would be a good argument against it: it is actually a lot easier to do the clear-up bit by bit whilst having a very concrete task such as looking for a file, than to simply go in and clear it up, as it were, just with the aim of clearing it up. If we do clear-up as part of another task, it is easier to stay focused on what clear-up is actually useful since you are searching for a particular item, and it is easier to stay motivated since you have in your mind at all times how this is really going to help to find this particular file, and other such files in the future.

See my book The Refactoring Workout for more on refactoring.

Tuesday, October 21, 2008

What refactoring IS

Let’s now state in the positive sense what refactoring is.

Refactoring is changing code internally, so that in some way or other, the code is internally in a better state. It aims to leave the code either clearer and easier to understand, or better structured, or containing less duplication, or simply with less code.

Refactorings change the code in such a way that externally there is no difference to the way the program functions or performs. If there has been a change that you can see on the outside – for example a button behaves slightly differently, or a calculation gives a different result – then this is not a refactoring. Often, a refactoring is done as part of a larger change which does change functionality – such as making a button behave slightly differently, or fixing a bug in a calculation – but the refactoring and the change in functionality are not the same thing.

Refactorings are objective improvements to code. Refactorings are changes which any reasonable programmer would agree have improved the code. It is true that, sometimes, whether a particular change would improve the code or not can be a matter of debate, but most refactorings are not in that category – most of them the change is a clear and easily acknowledged improvement.

A refactoring may be a change that is small and almost trivial, such as the renaming of a variable. Or it may be a change which is very large, such as separating out all the business logic which has somehow got tangled up with all the code dealing with the presentation.

Refactoring is a disciplined process, following careful steps to minimise as far as possible any chance of creating errors. Were ad-hoc improvements to the internals of a program in the past also refactoring? Yes, I believe they were. We would no doubt have performed them with as much care and attention as we knew how to do then. Refactoring applies best practices in making the changes in a disciplined way, and today our knowledge and understanding of how to perform the refactorings in a disciplined way has greatly improved.

Refactoring is a disciplined process in the same way that flying is a disciplined process. When, in 1903, Orville Wright had, what we term the first controlled, powered flight, it certainly required a large dose of discipline alongside much experimentation and daring. Nonetheless, the Wright brothers would no doubt look with great admiration and respect at the extensive and detailed modern-flight checklists. But regardless of the amount of discipline involved, flying is still flying. A flight done without performing any pre-flight checks is still flying. Similarly, refactoring done without any discipline is still, strictly speaking refactoring. Nonetheless, we should always seek to use the most recent understanding of how to perform refactorings with the most discipline possible. The person who does refactoring without being as disciplined as possible, is liable to end up in as difficult a situation as a pilot who ignores all pre-flight checks.
Refactoring is an ongoing process, to be applied at all stages of software development. It is something which you start applying even from the first week of coding (where code is growing at the fastest rate, and so often needs high amounts of refactoring to keep it in peak condition).

Refactoring is rather like a continual tug of war between the forces for and against the internal quality of the software. On the one side, pulling the software into a worse and worse structure internally are things such as tight schedules, sheer quantity of new code being added, junior developers, lack of experience of the technologies and so forth. On the other side, trying to pull the internal quality into as good a state as possible is refactoring. Yes, all the other forces on software are tending to pull it in a negative direction; that is why refactoring is so desperately needed, and also why it must be an ongoing process.

That is why, if we just focus our attention on trying to improve the causes of failure, even new projects are ultimately doomed. But this is what we like to do. With any new software development, we like to believe that if only this time we can get the specs written better, or develop in a more iterative way, or control the changes better, or ensure that the developers are more experienced, or any of dozens of other things – if only we can do this – then, ah yes, then at last, this time, this time our software will be great. This time, we will do things first time right, and we will keep them first time right.

No! No! No! This is doomed. The reasons that your next project will end up with the software gradually decaying beyond help are exactly the same reasons that the previous projects software has or will decay beyond help. Every cause that we have looked at is something that is sure and certain. Software entropy is a fact of life caused by all the things we have mentioned. Every cause that we have looked at will certainly pull your software in a negative direction. Improving each of the causes, whether it is by better specs, or better programmers, will only help to reduce these forces of entropy pulling software in the wrong direction.

There will always be factors pulling a program the wrong way, tending to make a program get worse and worse. There are many causes of software decay, pulling the program inexorably in the wrong direction; it is the natural lot of a programmer’s life. By all means, let us try and reduce the causes of software decay to a minimum. But the forces which pull the program the wrong way in quality will still exist and the program will still get worse.

There is only one thing which we can do to pull a program in the right direction, that is by a constant and continual application of refactoring. Refactoring is the one thing where we actively try to pull a program in the right direction, trying to make it better and better. The only way we can hope to maintain the long-term health of our programs is if we have some force which pulls the program in the right direction in quality; that force is refactoring and our programs cannot survive without it.

Refactoring is also like a person and exercise. Adding code is like eating food, refactoring is like taking exercise. As you eat more and more, and take no exercise, the tendency is to get fatter and fatter. When you exercise, you help the body to stay fit and healthy. Refactoring is to software as exercise is to people: it helps keep the program in a fit and healthy state. The more food the man eats (=the more code development which is going on), the more exercise the man needs to do (=the more refactoring is required). Just as if a man keeps eating food, he will become fatter and less flexible and more sluggish, so it is for your software, as you add code, unless you constantly refactor, they will become more and more puffed up with duplicate code, and slower and slower to work with and change and enhance.

See my book The Refactoring Workout for more on refactoring.

Tuesday, October 14, 2008

What refactoring is NOT

It can sometimes be helpful to explain what something is by saying what it is not.

Refactoring is not adding nor changing any functionality. The code should do exactly the same after any refactoring as before the refactoring. It should return exactly the same results, display exactly the same output, and react exactly the same to any input. Very often, if not almost always, refactoring is done as part of or as preparation for a change in functionality, but the refactoring itself does not change the functionality.

Refactoring is not about improving performance. Performance may or may not change due to a refactoring, but any such change in performance would be an incidental consequence rather than a direct aim of the refactoring. Of course, almost any change to the internal structure of a program will to some small degree change the performance of a program. If I divide a long method into two or three smaller methods, there will inevitably be some tiny change to the performance of the program. But any such performance changes are an inevitable side-effect of any changes to a program, including refactoring, rather than an objective, and in most cases are liable to be negligible.

Refactoring is not about stopping work for a few months to make a program in a good shape before carrying on; that can be done, but normally refactoring will be done as an ongoing task alongside normal development, just as a developer constantly tests his code, so a developer doing refactoring will be constantly doing refactoring.

Refactoring is not about ripping everything out completely, breaking everything and then trying to rebuild things with a hope that it’ll eventually be working again, but better. No. Refactoring is about moving from the existing program, and making single changes in small deltas so that at no stage is the program ever broken.

Refactoring is not like the car mechanic who completely strips down the engine into every tiny piece and then puts it all back together again. No. Refactoring is like the car mechanic who, while he happens to be working on a part of the engine on a task involving removing the spark plugs, will take a look at each spark plug in turn, checking the spark plug gap, replacing it in the engine, and checking each time that the engine still works correctly.

Refactoring is not about changing lots of things in a program at once. It is about changing one thing and only one thing at a time.

Refactoring is not about hacking into a change in a haphazard indiscriminate gung-ho approach with giant sweeping changes all at once. No, it’s about carefully making a single specific change in a series of small steps and testing after each step to ensure nothing has broken.

Refactoring is not about one programmer changing the work of another programmer to be in a style that he/she happens to like more. It’s about making changes which have real tangible improvements which, for the most part, can be objectively shown to improve the internal design of a program.

Refactoring is not only about big changes like extracting whole classes or breaking apart complex inheritance structures. No, refactoring is about even the simplest of changes such as replacing a magic number with a symbolic constant or introducing a temporary explaining variable to help clarify a complex expression, or simply renaming a method.

Refactoring is not only about tiny changes like renaming methods. It can be used to make giant changes to programs which truly turn upside down the way they work. Things like converting a program written in a procedural style to an object-oriented style, or restructuring a program to separate business logic from the presentation or user-interface layer.

And finally, refactoring is not about doing ‘busy’ work, with no real business value – something just to make the program look nicer or make the programmers feel good. No. Refactoring is about delivering real business value. It’s about making the program easier to change. It’s about making it easier and faster to add new functionality. It’s about reducing the likelihood of bugs and reducing the speed needed to find and fix them. It’s about extending the life of the program since it is more adapted to cope with the needs of the future. And while doing all of these things, there are even other unplanned bonuses which have real business value. Such as the program being more able to be redeployed for a variety of other tasks which were never part of the originally intended purpose. And such as the positive effect on team morale that people are working on a program of which they can be truly proud, rather than one of which they truly wish to see the back of.

See my book The Refactoring Workout for more on refactoring.

Tuesday, October 7, 2008

Refactoring Defined

What is Refactoring? Let me give my own definition:

Refactoring is a disciplined technique for improving software internally without changing its external behaviour.

Or, as Fowler defines it in his book:
“The process of changing a software system in such a way that it does not alter the external behaviour of the code yet improves its internal structure”

Or, from Fowler’s www.refactoring.com website:

“Refactoring is a disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior. Its heart is a series of small behavior preserving transformations. Each transformation (called a 'refactoring') does little, but a sequence of transformations can produce a significant restructuring. Since each refactoring is small, it's less likely to go wrong. The system is also kept fully working after each small refactoring, reducing the chances that a system can get seriously broken during the restructuring.”

For example, if I rename a variable within my code, I have (hopefully) chosen a more meaningful name, and thus the code has improved internally, but its external behaviour has (hopefully!) remained identical.

Another example. I have two classes which I notice share a degree of common functionality, so I create a parent class which contains the common functionality, and then in each of the two original classes I simply keep the functionality which is different. I have improved the software internally because I have reduced duplication and structured the code in a way that shows the relatedness between two previously separate classes, but yet without changing the external behaviour. The software should work exactly the same after the change as before the change.

Refactoring is a disciplined technique, that is, it is done systematically and according to a well-defined cycle of small step, test, small step, test, build.

So, to unpack the definition a little, refactoring is three essential things:
1. a disciplined technique
2. for improving software internally
3. without changing its external behaviour

See my book The Refactoring Workout for more on refactoring.

Tuesday, September 30, 2008

Who am I?

I have been working in IT for the best part of two decades. Istarted work as a programmer with IBM in Great Britain after graduating in Computer Science in 1985, and since then has worked in computing in the United States, Poland, and most recently Belgium, where I have worked as an IT contractor for a number of companies, both practicing and encouraging refactoring.

Though experience does not necessarily equate to knowledge or wisdom, I can at least claim a long experience in the world of software development. I have been programming since the days of ticker-tape and punched cards; I was taught to do object-oriented programming in IBM even before object-oriented programming languages existed outside research fields (we were taught to do OO in C), and as an IT contractor I consider it part of my profession to know as much as possible about all the technologies and methodologies which emerge.

In between contracting and writing my book on refactoring, I am learning Dutch, and have created a number of websites, of course applying strongly the principles of refactoring.

Wednesday, September 24, 2008

That even the plough boy may understand

This blog is about making everyone in IT understand refactoring, and it has always been a challenge to bring knowledge to the masses. In the 15th century, (yes, that’s even before Cobol and C++ was invented), when priests insisted the Bible was read in Latin, William Tyndale set out to translate the Bible into English, and when a priest attacked Tyndale’s beliefs, he replied " If God spare my life, before very long I shall cause a plough boy to know the scriptures better than you do!" If Martin Fowler’s book on refactoring is the Latin Vulgate, for the educated elite, this book on refactoring is for the plough boy of the software land, the everyman programmer and the busy IT manager.

And that is what excites me about this blog; it is my hope that all programmers throughout the land and all IT managers, will know about refactoring. And that the desperate need for refactoring and its clear benefits will become apparent, and that the world of software development will have taken another small step forward.
Tyndale was strangled and burned at the stake to thank him for his task; his last words reported to be, "Lord, open the King of England's eyes". Though I certainly don’t wish to share his fate, my hope is like his, that your eyes would be opened, though to different truths to the one’s Tyndale died for, to the glorious software truths which make up the subject of this blog, the subject of refactoring.

See my book The Refactoring Workout for more on refactoring.

Tuesday, September 23, 2008

Refactoring Introduction

The problem you always get with software is that over time it becomes harder and harder to change it, harder and harder to add new functionality, and harder and harder to fix bugs in it. This is because the internal structure of the program becomes worse and worse, making it more and more difficult to make all these changes. It is as though the program has become unfit. Refactoring is about how to keep the program in a healthy state so that it is as easy as possible to change it, so that it is as easy as possible to add new functionality, and so that it is as easy as possible to find and fix bugs in it. If the natural tendency of software is to become unfit, refactoring is about how to fight that tendency and to keep the program as healthy as possible.

See my book The Refactoring Workout for more on refactoring.