Stories
Slash Boxes
Comments

News for nerds, stuff that matters

Refactoring: Improving the Design of Existing Code

Posted by Hemos on Thu Sep 23, 1999 08:55 AM
from the solid-advice-for-programmers dept.
SEGV has returned and is continuing his excellent set of reviews. This time around, we're looking at Martin Fowler's (with Kent Beck, John Brant, William Opdyke, and Don Roberts) Refactoring: Improving the Design of Existing Code. Click below for more details.
Refactoring: Improving the Design of Existing Code
author Martin Fowler with Kent Beck, John Brant, William Opdyke,
pages 431
publisher Addison-Wesley
rating 9/10
reviewer SEGV
ISBN
summary Just what the working programmer ordered: a catalogue of practical refactorings with solid advice on when and how to apply them.

Overview

This book could very well do for refactoring what the "Gang of Four" book did for design patterns. In fact, with the number of contributing authors, this might well become known as the "Gang of Five" book. (They contributed content to chapters 3 and 12 through 15.)

Organization

Refactoring leaps in feet first with an extended example. I found this to be a surprisingly effective opener: it didn't overwhelm me, and left me hungry for more. The first chapter follows a sample program through several incremental refactorings, and the reader gets the idea via osmosis.

To illustrate the technique of refactoring, the first chapter presents the original code on the left page, and the resulting code on the right, with changes in bold. This presentation, coupled with explanatory text, makes it easy to see what's going on and focus on what's happening. It's as if you're looking over the author's shoulder as he edits, compiles, and tests code in his development environment.

What is Refactoring?

Now that you've done a refactoring, you might be curious to know more about what refactoring is. The next few chapters provide the relevant background.

Refactoring is what the book's subtitle suggests: changing code in in ways that preserve behaviour, but improve the way that behaviour is generated. This could be as trivial as renaming a method, or as tricky as separating domain and presentation classes.

Why go through this trouble? In the end, the code is different but it acts the same; there has been no new functionality added. Why? You do this to place yourself in a better position to add new functionality to the software. If you don't, you eventually end up with spaghetti code that is unmaintainable and will not support new functionality at all.

I think anyone who has worked on real code can appreciate the need for refactoring. In fact, most good programmers already do it, although perhaps only on a subconscious level. What this book aims to do is to raise that ad-hoc activity to a higher level of applied technique. Just as there are principles and practices in GUI design (as opposed to merely throwing widgets together randomly), there are principles and practices in refactoring activity: this book catalogues them.

Catalogue

Sandwiched between introductory and summary chapters is the meat of the book: a catalogue of over seventy refactorings. This catalogue follows in the footsteps of the highly successful Design Patterns format: Pattern Name and Classification, Intent, Also Known As, Motivation, Applicability, Structure, Participants, Collaborations, Implementation, Sample Code, Known Uses, and Related Patterns. Since the individual refactorings are less complex than patterns, this catalogue uses the format: Name, Summary, Motivation, Mechanics, and Examples.

The idea is the same. The name and summary provide a definitive vocabulary and a reference-card example. The motivation explains the relevance of the refactoring. The mechanics cover the step-by-step details of how the refactoring is executed. Then a series of examples demonstrate the variations.

Applicability

I like the catalogue. Although some refactorings seem deceptively trivial, it is useful to have them laid out in step-by-step detail. You never know when you will make a mistake, and when you absolutely positively must fix a bug or add a feature by the next day, and need to refactor to do it, slow and steady wins the race.

Further, other refactorings are not so trivial and familiar, and it is certainly useful to have their traps and pitfalls exposed. Frequently, they rely on the smaller refactorings themselves.

I can see this book becoming well-used in a shop with plenty of production code.

Supplementary Material

The non-catalogue chapters are informative as well. I especially appreciate the metaphor of bad smells in the code: the "if it stinks, change it" philosophy is the perfect counter-point to the oft-cited "if it ain't broke, don't fix it" mentality.

The chapter on refactoring tools discusses the possibility of automating much of the mechanical work of refactoring. Although there is a Refactoring Browser for Smalltalk, I suspect that Java and C++ versions are a little ways off. I'd wager that, as with the UML, tool support will lag industry practice for some time.

Style

As always, the author's writing style is down-to-earth and easy to read. Martin tells you straight up what he's found useful and what he hasn't. He tells you where he's made mistakes, and where the risk is less pronounced.

I like the way he goes through an example, then goes through it again under different conditions, thereby revealing the many-splendoured variations. Frequently he continues examples that were left off from other refactorings.

Plenty of further reading is suggested; I always like that.

Flaws

The book has a Java focus, and that is the language used for the examples. There is some mention of Smalltalk and C++, but not much; far less than Design Patterns, for example. Still, the book is quite understandable to anyone with object-oriented development experience.

The book references design patterns; some refactorings even apply and manipulate patterns. However, I wish there were more direct references to the Design Patterns book. That would especially help those new to both refactorings and design patterns.

There are a few minor typos (nothing major), so check the author's web site for errata and try to get a recent printing if you can.

Recommendation

It's no secret that I think this is a book whose time has come. I'm hoping it will codify my approach to refactoring, to help me be more efficient in my development.

I recommend this book as both a practical catalogue, and as a general work on the theory and practice of refactoring. I think that the refactoring community will grow much as the patterns community before it, and that we will see more published on the subject.

Until then, this book is a good start.

Purchase this at Amazon.

TABLE OF CONTENTS

Foreword
Preface
1. Refactoring, a First Example
2. Principles in Refactoring
3. Bad Smells in Code
4. Building Tests
5. Toward a Catalog of Refactorings
6. Composing Methods
7. Moving Features Between Objects
8. Organizing Data
9. Simplifying Conditional Expressions
10. Making Method Calls Simpler
11. Dealing with Generalization
12. Big Refactorings
13. Refactoring, Reuse, and Reality
14. Refactoring Tools
15. Putting It All Together
References
List of Soundbites
Index

This discussion has been archived. No new comments can be posted.
Display Options Threshold:
The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
(1) | 2
  • Important... by Wiggins (Score:1) Thursday September 23 1999, @04:13AM
  • Refactoring and Extreme Programming by Anonymous Coward (Score:2) Thursday September 23 1999, @04:13AM
  • Good book (Score:3)

    by Desdicardo (71571) on Thursday September 23 1999, @04:14AM (#1664622)
    I've owned this book for a couple months now and I feel it was definitely worth buying. The section on self-testing code was quite useful, even if it was short. My one complaint is that the book does not address how to apply refactoring in an environment that closely tracks SPR's. On a project where there is formal witness testing you usually try to keep SPR's small with limited impact. This is exactly the opposite of how refactoring works... i.e. redesign the whole thing if it is the Right Thing to Do. While self-testing code helps, having to pay for a complete formal regression test for each SPR would get expensive. Other than that, however, this is an excellant book. I would be very happy if it attracted a following as large as the Design Patterns book.
  • How original is this idea? by Chalst (Score:1) Thursday September 23 1999, @04:24AM
  • by Anonymous Coward on Thursday September 23 1999, @04:30AM (#1664626)
    The more I write code, the more I realize that it is like any other kind of writing. And after years of looking at garbage spagheti code, I have come to the conclusion that the best way to raise the level of coding is for experienced and talented programmers to review the code of others, making revisions if necessary. Many programmers would no doubt scream in protest, and this too would be a good thing: in my experience the worst programmers are also the ones with the most vanity (especially in regards to their code).
  • No amount of programming methology... by GoofyBoy (Score:2) Thursday September 23 1999, @04:36AM
  • Re:No amount of programming methology... by Simes (Score:2) Thursday September 23 1999, @04:44AM
  • Re:No amount of programming methology... by ruud (Score:1) Thursday September 23 1999, @04:46AM
  • Re:No amount of programming methology... by Anonymous Coward (Score:1) Thursday September 23 1999, @04:57AM
  • Re:'Well' architectured systems suck by dilettante (Score:1) Thursday September 23 1999, @04:58AM
  • by tuffy (10202) on Thursday September 23 1999, @04:59AM (#1664634) Homepage
    I don't spend a lot of time on comments the first time around writing things, but invariably I comment the second time around as an eternal reminder why I did things the way I did. This holds especially true for the low-level bits of logic I try to abstract away first and hardly look at until the boss calls for some tweaks.

    Too many comments can be as bad as too few, and trying to get the right mix is somewhat of an art that I still haven't quite mastered. But I think using them as reminders has come in very handy.

  • SPR? by Chris Parrinello (Score:1) Thursday September 23 1999, @05:02AM
  • Re:SPR? by Desdicardo (Score:2) Thursday September 23 1999, @05:14AM
  • Anti-Patterns by hawkfish (Score:1) Thursday September 23 1999, @05:25AM
  • Re:No amount of programming methology... by Ed Avis (Score:1) Thursday September 23 1999, @05:27AM
  • Re:No amount of programming methology... by UnknownSoldier (Score:1) Thursday September 23 1999, @05:29AM
  • Re:How original is this idea? Doesn't matter by Jez (Score:1) Thursday September 23 1999, @05:33AM
  • It doesn't have to be *original*... by Simon Tatham (Score:1) Thursday September 23 1999, @05:42AM
  • Re:No amount of programming methology... by UnknownSoldier (Score:1) Thursday September 23 1999, @05:46AM
  • Re:'Well' architectured systems suck by Overt Coward (Score:1) Thursday September 23 1999, @05:48AM
  • "Anyone have any others that every developer "... by GoofyBoy (Score:1) Thursday September 23 1999, @05:55AM
  • But refactoring applies to small programs too by jflynn (Score:2) Thursday September 23 1999, @06:03AM
  • Re:Finally, Software Editing Arrives... by Anonymous Coward (Score:2) Thursday September 23 1999, @06:06AM
  • Good structure and good variable names help you understand what is going on, but don't help explain why.

    Comments the just restate what the code says, like

    foocnt++; /* increment foocnt */

    are absolutely useless, and those who put them in code need to be taken out and beaten. But comments like

    foocnt++; /* yes, this situation counts as a foo */

    (ok, a bit of a contrived example) are more useful. Function and module headers that explain design and interface are very useful, and should be required on all sizeable projects, IMHO.

    Inside the code itself, perhaps the best way to comment is to write down what a section of code is going to do before you write it. Thus, you write the comment

    /* now we have to mung the frobnitz for each element of the barbaz array */

    before you write the code that loops over the array . (Assuming that the code is more complex than for (i=0;i) Then, when you're going back over the code, and you see something that makes you pause for a second - or even a quarter of a second - and say "why are we doing this?", comment it. Trust me, the guy who inherits your code will love you for it.

    (I have a calligraphic button that says "Code as if whoever maintains your code is a violent psychopath who knows where you live." Great advice. Anyone know the original source?)

    Anyway, I'm glad that I know have a term for refactoring. I've been doing it for years, but it was sometimes difficult to explain to management what had to be done and why. I shall add this tome to my purchase queue.

  • Re:No amount of programming methology... by GoofyBoy (Score:1) Thursday September 23 1999, @06:07AM
  • Re:No amount of programming methology... by Patrik Nordebo (Score:1) Thursday September 23 1999, @06:09AM
  • Re:No amount of programming methology... by Mr. Slippery (Score:1) Thursday September 23 1999, @06:10AM
  • Refactoring & Extreme Programming by Will Sargent (Score:1) Thursday September 23 1999, @06:15AM
  • Re:No amount of programming methology... by raytracer (Score:1) Thursday September 23 1999, @06:21AM
  • C++ maybe..but Java? by tuffy (Score:1) Thursday September 23 1999, @06:23AM
  • I am stealing this! by GoofyBoy (Score:1) Thursday September 23 1999, @06:24AM
  • Re:How original is this idea? by cjeris (Score:1) Thursday September 23 1999, @06:28AM
  • Whoops. by GoofyBoy (Score:1) Thursday September 23 1999, @06:29AM
  • ...or *what* - not *how*... by deepone (Score:1) Thursday September 23 1999, @06:31AM
  • Thoroughly Agree by FatSean (Score:1) Thursday September 23 1999, @06:42AM
  • Analysis Paralysis (Score:3)

    by kuro5hin (8501) on Thursday September 23 1999, @07:02AM (#1664663) Homepage
    In my experience, the times when 'well' architectured systems suck is when some manager with experience in, say, Visible Analyst decides it's up to him to engineer the whole system from the get-go, unencumbered by any knowlege of the language it'll be written in, or the strengths and limitations of that language.

    The most important thing about all of this is that software development goes in cycles. First you make it work, then you make it right, then you make it fast. Leaving out any of these steps is very bad.

    Another very bad thing is when you have the whole system planned out in excruciating detail before you write line one of code. Inevitably, one of your assumptions will turn out to be totally unworkable, and if it's already set in stone, that will probably break everything else. Generally you have to sketch the broad strokes, fill in the major code, find out what works and what doesn't, throw away what you've done so far, and start for real. That's just the way it is, and if you don't plan to throw away your first try, you'll just end up being overbudget and late when you have to throw it away anyway.

    ----
    We all take pink lemonade for granted.

  • Re:Finally, Software Editing Arrives... by Anonymous Coward (Score:1) Thursday September 23 1999, @07:07AM
  • Commenting style should be based on language. by Analogue Kid (Score:1) Thursday September 23 1999, @07:10AM
  • Re:Refactoring and Extreme Programming (links?) by Mike Miller (Score:1) Thursday September 23 1999, @07:24AM
  • Old Ideas; Newly Codified by SEGV (Score:1) Thursday September 23 1999, @07:53AM
  • Re:Finally, Software Editing Arrives... by flanker (Score:2) Thursday September 23 1999, @07:56AM
  • C++ and elegance by SEGV (Score:1) Thursday September 23 1999, @08:01AM
  • Comments and/or dependencies... by CJ Hooknose (Score:1) Thursday September 23 1999, @08:17AM
  • Re:C++ maybe..but Java? by Zoltar (Score:1) Thursday September 23 1999, @08:18AM
  • by gid-foo (89604) on Thursday September 23 1999, @08:24AM (#1664678)
    Hear hear, this is the big problem with code reviews, in my experience. They tend to either be a rubber stamp or a tedious examination of religious principles (i like 2 tab indents, not 4, or your open bracket should be on the next line not following your function declaration, etc). In a best case scenario you actually have engineers reading over your code and looking for problems or bogus assumptions. Too often most "engineers" are mediocre and uninterested in anything but widening their cubicle-monkey asses. Egoless development doesn't just apply to the individual writing the code but to all coders in the shop. On another note, in an Intel style environment where the whole goal is to make yourself appear superior to your colleagues by putting down their ideas and abilities (you're manager won't hire anyone potentially better than them because they are in direct competition with their own engineers) code reviews are merely political tools. In other words, an excellent chance to sink the hatchet into your cubicle mate's back.
  • Re:Refactoring and Extreme Programming (links?) by Lucy Linux (Score:1) Thursday September 23 1999, @08:26AM
  • Re:'Well' architectured systems suck by gid-foo (Score:1) Thursday September 23 1999, @08:27AM
  • Re:C++ and elegance by cjeris (Score:2) Thursday September 23 1999, @08:31AM
  • Good idea, but what about politics... by randomthought (Score:2) Thursday September 23 1999, @08:40AM
  • The problem with abstraction... by AJWM (Score:1) Thursday September 23 1999, @09:01AM
  • Re:C++ and elegance by SEGV (Score:1) Thursday September 23 1999, @09:09AM
  • I feel your pain by FatSean (Score:1) Thursday September 23 1999, @09:14AM
  • Re:I am stealing this! by mayoff (Score:1) Thursday September 23 1999, @09:17AM
  • Re:No amount of programming methology... by A Big Gnu Thrush (Score:2) Thursday September 23 1999, @09:21AM
  • Doing it over by Jeremi (Score:1) Thursday September 23 1999, @09:25AM
  • D'Oh! by A Big Gnu Thrush (Score:2) Thursday September 23 1999, @09:26AM
  • Re:No amount of programming methology... by speek (Score:1) Thursday September 23 1999, @10:01AM
  • The book covers this by SEGV (Score:1) Thursday September 23 1999, @11:25AM
  • I do "un-glowing" reviews by SEGV (Score:1) Thursday September 23 1999, @11:54AM
  • Re:I am stealing this! by GoofyBoy (Score:1) Thursday September 23 1999, @12:09PM
  • I do respect Waterloo grads. by GoofyBoy (Score:1) Thursday September 23 1999, @12:17PM
  • AntiPatterns by discHead (Score:1) Thursday September 23 1999, @12:28PM
  • Re: C++ and elegance by Chalst (Score:2) Thursday September 23 1999, @12:53PM
  • Re:The book covers this by randomthought (Score:1) Thursday September 23 1999, @01:11PM
  • Re:'Well' architectured systems suck by SEGV (Score:1) Thursday September 23 1999, @01:36PM
  • The hard part is maintaining it.. by Gorimek (Score:1) Thursday September 23 1999, @03:23PM
  • Re:Good book by eauz (Score:1) Thursday September 23 1999, @04:03PM
  • Re:No amount of programming methology... by eauz (Score:1) Thursday September 23 1999, @04:10PM
  • Respect the Wiki! by Em (Score:1) Thursday September 23 1999, @10:38PM
  • Re:No amount of programming methology... by Simes (Score:1) Thursday September 23 1999, @11:31PM
  • Functional Languages by SEGV (Score:1) Friday September 24 1999, @06:05AM
  • Re:Old Ideas; Newly Codified by SEGV (Score:1) Friday September 24 1999, @06:11AM
  • See my web page by SEGV (Score:1) Friday September 24 1999, @06:26AM
  • Comments are Like Newspaper Headlines by Tablizer (Score:1) Friday September 24 1999, @08:46PM
  • favorite computer books by bharlan (Score:1) Saturday September 25 1999, @10:18AM
  • I bought the book---it's worth it! by Max Hyre (Score:1) Friday October 01 1999, @06:45AM
  • 23 replies beneath your current threshold.
(1) | 2