Refactoring: Improving the Design of Existing Code by MartinFowler, The AddisonWesley Object Technology Series
ISBN 0201485672 Hit the shelves in mid-June of 1999. Sometimes known on Wiki as the RefactoringBook.
Perhaps this book can serve as the starting point and dictionary for a RefactoringLanguage, much as PatternNames?, used together, can form a PatternLanguage.
I picked up a copy at JavaOne. It's a wonderful book. It is organized roughly along the lines of the GangOfFour book - some introductory chapters about what refactoring is, where it came from, and why you should care, followed by a catalog of refactorings. However, I found it to be a much more pleasant book to read than DesignPatterns (as useful and important as that book is, I don't think it's an easy read).
Like Fowler's book UmlDistilled, Refactoring is subversive. Along the way, readers learn about many, if not most, of the XP techniques and principles: pair programming, continuous unit testing (and writing unit tests first), YouArentGonnaNeedIt, OnceAndOnlyOnce, and others. -- GlennVanderburg
If you've read SmalltalkBestPracticePatterns, you'll find this book is quite similar in a lot of ways. As well as showing you better ways to use the language, this book shows you how to take poor code and improve it by applying those patterns. It uses JavaLanguage rather than SmalltalkLanguage and is much easier to apply directly for those of us using CeePlusPlus. I couldn't recommend this book more! -- JohnBurton?
Kudos, Martin! This book is fabulous! Within an hour, I had decided that I will order several copies to spread around my company. And I was thrilled when I showed it to a colleague first thing this morning only to learned that he ordered it this weekend after discovering it (and reading chapter 1) at a local bookstore. -- KielHodges
I'd like to thank Martin for putting together some of the theory of Refactoring with some actual practice here. Writing code is not simply written, but evolved, and this book gives some very specific methods and pathways for common programming techniques.
The odd thing is, like DesignPatterns, once you have seen the pattern (or idiom, or whatever you want to call it) you think to yourself Oh yeah, I do that (aka I HaveThisPattern). But having a roadmap in front of you is a thought aid and useful reference point when you're in the thick of code without a flashlight.
I must also thank this book for introducing me to the JavaUnit (actually JUnit, but that's not wiki friendly) testing framework. I would have liked to have seen more focus on the pre-emptive unit testing methodology as it seemed interesting, but I am concerned how it would scale up to large scale software projects, specifically client/server or distributed systems.
-- WillSargent
RefactoringImprovingTheDesignOfExistingCode seems to suggest that LocalVariablesAreBad.
Or at least that they can be replaced with something better like a query. -- pg
One thing that I found confusing was the UML class diagram of JUnit on page 92. It shows that TestSuite and TestCase both implement <<interface>> Test. That much was reasonable, and consistent with MartinFowlersJunitPaper. However, it also shows that TestSuite extends zero or more Test. -- PatrickParker
That looks like an erratum. The relationship should be aggregation, rather than inheritance. That is, a TestSuite contains zero or more Tests.
JUnit uses the CompositePattern. TestSuite both implements Test and contains zero or more instances of Test.
I just finished reading Chapter 6 and I have a question regarding ReplaceMethodWithMethodObject. I have used this pattern before, creating an InnerClass to replace a classes method. The book makes no mention of using InnerClasses, and I was wondering if there are any reasons why you might not make the new MethodObject an InnerClass?
Sure, why not? It's a simple extension of ReplaceMethodWithMethodObject.
Personally I consider ReplaceMethodWithInnerClass? to be the obvious implementation of the pattern. The question I was asking is: "Are there any times when using an inner class is inappropriate for this Pattern?"
Having finished reading Chapter 8 I thought I should ask why there was no treatment of the threading issues inherent in DuplicateObservedData?. The issue is that any modification of the DomainObject will be propagated to the GUI widgets automatically via the Observer update() method. As this occurs within the setter method of the DomainObject, it will run within the updating Thread not the GUI Thread. As neither AWT nor Swing are ThreadSafe, this can lead to DataRace?'s and resulting bugs.
The solution is for the DomainObject to register an update with either javax.swing.InvokeAndWait?() or javax.swing.InvokeLater?(). Note that if you use InvokeAndWait?() you must be careful you avoid DeadLock, InvokeLater? does not have this problem however it will leave your GUI Object and your DomainObject out of sync until the update runs.
Both functions use Runnable as a FunctorObject, in most cases I use AnonymousInnerClasses for this.
-- AndraeMuys
Excellent book - wish I'd come across it sooner. Quite practical/hands on, though with decent explanations. I found the GoF book unreadable, so I bought a clone, which still makes some of the patterns clear as mud. This book however couldn't be clearer, and what's more it's easy to read - written with a light touch and interspersed with humour. I was pleased to see that I was already using most of the refactorings - but having a good reason why is very reassuring. Still not taken 'Change Unidirectional Association to Bidirectional' on board though - I'm sure I've needed to achieve the same end before, but I can't figure out how else I would have done it. 10/10 for MartinFowler & co. -- DannyAyers
Comments on the book by a self-described RelationalWeenie moved to RefactoringIsNotRelational. (Any WikiMaster should feel free to provide a better name for the page. -- StevenNewton)
DotNet Refactoring Tutorial:
You know, I'm still not happy with the use of the term design in relation to refactoring. Design happens before coding. Code is supposed to reflect design. Refactoring can improve implementation, but it really can't affect design. If it does then there was something wrong with the design in the first place, now wasn't there?
I beg to disagree. See EmergentDesign.
See also RefactoringToPatterns