Follow Slashdot blog updates by subscribing to our blog RSS feed

 



Forgot your password?
typodupeerror
×

Refactoring: Improving the Design of Existing Code 184

kabz writes "Refactoring (as I'll refer to the book from here on in) is a heavy and beautifully produced 418 page hardback book. The author is a UK-based independent consultant who has worked on many large systems and has written several other books including UML-Distilled. Refactoring is a self-help book in the tradition of Code Complete by Steve McConnell. It defines its audience clearly as working programmers and provides a set of problems, a practical and easily followed set of remedies and a rationale for applying those techniques." Read below for the rest of Johnathan's review.
Refactoring: Improving the Design of Existing Code
author Martin Fowler with Kent Beck, John Brant, William Opdyke and Don Roberts.
pages 431
publisher Addison-Wesley
rating 9/10
reviewer Jonathan Watmough
ISBN 0201485672
summary expands and formalizes the idea of applying explicit refactorings
Code refactoring is the process of restructuring code in a controlled way to improve the structure and clarity of code, whilst maintaining the meaning of the code being restructured. Many maintenance problems stem from poorly written code that has become overly complex, where objects are overly familiar with each other, and where solutions implemented expeditiously contribute to the software being hard to understand and hard to add features to.

Typically refactorings are applied over a testable or local scope, with existing behavior being preserved. Refactoring as defined in this book is not about fixing bad designs, but instead should be applied at lower levels.

Testing a la Extreme Programming is emphasized as a control for ensuring that program meaning is not changed by refactoring. It is not over emphasized, and this is not a book about testing, but it is often mentioned and stays in the background through the book.

The refactorings presented in the book are not intended as a comprehensive solution for all problems, but they do offer a means to regain control of software that has been implemented poorly, or where maintenance has been shown to simply replace old bugs with newer ones.

The book is divided into two main sections, introductory material that introduces and discusses refactorings, and a lengthy taxonomy of refactorings that includes both examples and further discussion. The introductory material consists of a long worked example through simple Java code that implements printing a statement for a video store. Despite the simplicity of the code, Fowler shows in clear detail where improvements can be made, and how those improvements make the code both impressively easy to understand, and easy to maintain and add features.

Several key refactorings are demonstrated in the opening chapter including Extract Method, Move Method and Replace Conditional with Polymorphism. This is a book about programming in the object oriented paradigm, so as you might expect, the first two refactorings refer to extracting and moving object methods either into new methods, or between objects. The third example provides a means to replace special cased behavior in a single object type by deriving a sub type of the object and moving type specific code to the sub types. This is a fundamental technique in object oriented programming, and is discussed here in practical terms.

Now that several actual refactorings have been introduced, Fowler provides a solid and well thought-out discussion of the why's, when's and when not's of refactoring. For example, code can decay as features are added, and programmers special-case, or bodge additional functionality into existing objects. Fowler argues that the bitrot and decay makes software more unreliable, leads to bugs and can accelerate as the problem gets worse. Faced with these problems, refactoring should be used to improve local design and clean up and improve code, leading to better software, that is easier to maintain, easier to debug, and easier to improve with new features as requirements change.

However, there is a caveat, in that since software functionality should remain unchanged during refactoring, the process of refactoring consumes resources, but provides no easily measurable value. Fowler confronts this issue in a section that discusses how to communicate with managers, that you are performing refactoring work. He denies being subversive, but his conclusion is that refactoring should essentially be folded in with normal work as it improves the overall result.

This is a bit like goofing off on the basis that you'll think better after 20 minutes of fooseball. I'd definitely subscribe to that theory, but many others may not.

Kent Beck guests in Chapter Three for a review of the issues in typical software that suggest a refactoring may be needed. This chapter is entitled Bad Smells in Code, and most of the smells presented will be familiar to any reasonably experienced programmer, and they will be a great learning experience for less experienced programmers. I got the same feeling reading this chapter as I did when I first read Code Complete. Here was someone writing down names and describing problems that I had a vague unease about, but was too inexperienced to really articulate or do something about. Typically the refactorings address the same kind of issues that a code review with a skilled experienced programmer would address. Long parameter lists, too long methods, objects delving about in each others private variables, case statements, related code spread across different objects etc. None of these problems are debilitating in themselves, but added up, they lead to software that can be prone to error and difficult to maintain.

Most of the remaining substance of the book, 209 pages, is given over to a taxonomy of refactorings. These 72 refactorings are covered in detail with comprehensive simple examples presented in Java. Each refactorings is given a clear name, a number and a line or two of descriptive text. The motivation for the refactoring is then discussed, often including caveats and cautions. The mechanics of implementing the refactoring are then listed, with 1 or more (and often more) examples of implementing the refactoring. Refactorings range from the very simple to more complex examples such as Convert Procedural Design to Objects.

Due to the difficulties of reproducing large and complex sections of code, Fowler sticks with relatively simple examples. These seem to grate on him more than the reader, and he can come across as somewhat embarrassed when we look at the employee, programmer, manager pay example for the tenth time. I certainly didn't have a problem with it though.

This is a very well written and fun to read book. I personally feel that much of the material is implied by from Code Complete, but Fowler does a fantastic job of expanding and formalizing the idea of applying explicit refactorings. Much like Code Complete gave a motivation for keeping code well commented and laid out, this book presents the case for care and feeding of how to structure software. To fight bitrot and technical debt, poorly structured and unclear code should be targeted and refactored to improve structure and clarity. This gives a very real payback in terms of less required maintenance, and ease in adding features later on down the line.

Despite the fact that all the examples are in Java, the ideas are easily transferable to C++ or any procedural object oriented language. I highly recommend this book.

You can purchase Refactoring: Improving the Design of Existing Code from amazon.com. Slashdot welcomes readers' book reviews -- to see your own review here, read the book review guidelines, then visit the submission page.
This discussion has been archived. No new comments can be posted.

Refactoring: Improving the Design of Existing Code

Comments Filter:
  • Old news. (Score:5, Informative)

    by Kaz Kylheku ( 1484 ) on Wednesday January 09, 2008 @01:39PM (#21970862) Homepage
    Reviewed back in 1999 on Slashdot.

    http://books.slashdot.org/article.pl?sid=99/09/16/1333202 [slashdot.org]
  • Re:Java-Specific (Score:4, Informative)

    by cyberkreiger ( 463962 ) on Wednesday January 09, 2008 @02:12PM (#21971356) Homepage
    It presented examples in Smalltalk and C++.
  • Re:Java-Specific (Score:1, Informative)

    by Anonymous Coward on Wednesday January 09, 2008 @02:51PM (#21971926)

    GoF presents examples in both SmallTalk and C++, and most of the patterns are not directly applicable to C++, in the sense that if you just implement them as-written terrible things will happen.

    An obvious example of this is the publish/subscribe (Observer) pattern. I once worked with an incompetent developer who had the fixed belief that you could just take GoF examples and use them without modification. So he did, and the first time an observer removed itself from the subscriber list during a notification call his crappy code fell over due to an invalid iterator. And then there were the fun things that happened when any subscriber threw an exception during notification...

    The GoF patterns are excellent, and any good developer should know and use them. But simply taking them verbatim out of the book without thinking at least a little about language-specific implementation issues can land you in a big, hard-to-debug mess. No amount of rote copying will ever replace actual competency.
  • Re:MakeWork (Score:4, Informative)

    by stg ( 43177 ) on Wednesday January 09, 2008 @03:08PM (#21972196) Homepage
    First - you do realize the 2nd edition of Code Complete has a whole chapter on Refactoring, right? AND it recommends the other book for more details?

    Have you actually read the book or are you just going from the review? Most of the methods are designed to work in a very small scale.

    Examples - have you...
    - Moved some code in the middle of a method to a separate method to make your code clear or re-usable?
    - Renamed a variable with an unclear name?
    - Added an intermediate variable for a complex calculation?
    - Moved a complex boolean expression into a well-named boolean function?
    - Added/removed a parameter to/from an existing method?

    These are all refactorings, although some of the simplest. You might say that is just common sense, but that is kind of the point of it, and the particular steps are designed so that you won't screw up the code with common mistakes. Many refactoring tools exist too, and they are quite useful - for example, when adding a parameter to a method, one of my refactoring tools show me where that was used and I can edit any with a click (and also note if they all need it, or if I should give it a default value). If I change the name of a method, it can replace everywhere it is used (a search and replace can do the same, except if another object has a method with the same name it will screw things up - so you have to watch each replace carefully).

    You might also note that many refactorings match other concepts in Code Complete.

    None of these are supposed to "fix" a broken design by itself. They are meant to slowly improve the code so that it is easier to keep working on it.
  • by Cederic ( 9623 ) on Wednesday January 09, 2008 @04:56PM (#21974296) Journal

    XP is an Agile methodology, but there are many others. Not all methodologies work for all organisations, so someone that knows agile principles can help a company adopt an appropriate methodology without forcing them to follow any specific one. The principles behind them all are much the same. And if someone is requiring reams of documentation/paperwork as part of an agile methodology then either their methods are not agile, or the customer is demanding the documentation (in which case they should hire technical writers and not developers).

    These days OO means much the same as it always used to. Basic OO principles are still very valid. ISomething interfaces are very strongly a Microsoft thing, no languages I've worked with have ever needed that. The use of Abstract base classes, factories, etc results from the use of design patterns, and if you think those are bad then you're in disagreement with every software engineer I know.

    Refactoring as a technique is very sensible. Fowler's book is exceedingly well written, and the approaches he recommends very sensible. The people factors (explaining things to project managers) are complicated, but the underlying refactoring mechanisms are sound. Don't confuse the tools and techniques with the difficulties of getting them accepted within an organisation.

    If you think that nowadays refactoring means going through turning everything into an interface+impl+factory then frankly you're not following the book, even remotely.

    Sounds to me like you've entered a Microsoft shop, you're receiving very poor guidance, and you're attempting to use technology/languages that you aren't sufficiently trained/expert in. You have my sympathy, but don't let that scare you away from the very real benefits that OO programming, design patterns, agile development activities and refactoring can provide. At the very least make sure the people around you stop using incorrect terms to describe the things they're doing.

  • by anomalous cohort ( 704239 ) on Wednesday January 09, 2008 @06:31PM (#21975798) Homepage Journal

    I'm surprised that the companion web site [refactoring.com] for the book hasn't been posted here yet. It's the catalog [refactoring.com] that will be of most interest.

For God's sake, stop researching for a while and begin to think!

Working...