Slashdot Mirror


Refactoring: Improving the Design of Existing Code

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.

11 of 184 comments (clear)

  1. who doesn't know about Refactoring? by StandardDeviant · · Score: 3, Interesting

    I don't mean to be a wet blanket, but the book has been out for quite some time -- checking Amazon, July of 1999. It is pretty great, and I would recommend it to those who somehow managed to miss it up to this point, but a review almost nine years later? Slow news day much?

    On the other hand, maybe periodically prodding towards the direction of higher internal quality (to be distinguished from external quality, that which is perceived in a black-box fashion by your customers, the relationship between these two qualities is of course a matter of much friction and debate between the managing and laboring classes) isn't a bad call. Lord knows any extra ammo to convince people that this is worthwhile is appreciated. As much as we like to think of ourselves as poets, I sometimes think the traditional profession most software development resembles is "butcher" or "janitor", just one messy hack-job and sweep under the rug after another after four or five decades of which you can retire and grumble on the beach about putting cyanide in the guacamole, fondly reminiscing about your red swingline or asr-33 or what have you.

  2. Java-Specific by justasecond · · Score: 1, Interesting

    One point about the review: The note about the examples being transferrable to C++, etc. is a little off; some of the refactor techniques are basically workarounds for Java quirks. In fact, I've always felt that the book should have been called "Refactoring: Improving the Design of Existing Java Code".

    Not a bad read overall, but it could have been made better by presenting examples in different languages, a la the GOF Design Patterns book.

  3. Love refactoring but primary problem is legal by Maxo-Texas · · Score: 4, Interesting

    "new" code is a capital investment and gets very high tax benefits.
    "refactored" code is a pure cost.

    I do a lot of refactoring but i always have to sneak it in under the cover of a "new" project instead of a "bug fix" project.

    --
    She was like chocolate when she drank... semi-sweet at first and then increasingly bitter.
    1. Re:Love refactoring but primary problem is legal by Surt · · Score: 2, Interesting

      Refactored code is new code to do an existing job. Does Microsoft not get to write down its investment in each new version of windows because it does the same job?

      --
      "Who is the Journal of Quantum Physics going to believe?" --Stephen Hawking
    2. Re:Love refactoring but primary problem is legal by Maxo-Texas · · Score: 2, Interesting

      I do not think any of you guys got my point so I'll clarify.

      From here:
      http://www.pkftexas.com/pkf/NewsBot.asp?MODE=VIEW&ID=15&SnID=2
      The entrepreneurial owner of a growing business would like to expand into other cities and states, but is hesitant. He does not believe his current accounting software will be able to handle the increased transaction load and produce the type of management reports he needs to make effective decisions, and the cost of the next tier software has always been a little out of reach. Under the 2003 Act, the business could expense the first $100,000 of the cost of the next tier accounting software and could immediately save $34,000 in taxes, using a 34% tax rate.

      In other words, "new" software is 2/3 the price of the same code done as maintenance code.
      So the ROI on your 100,000 maintenance change must be at least 34,000 to be equally justified to replacing the code with a new 100,000 project.

      I know that there are huge benefits to refactoring code- but there are huge tax advantages (that translate to large real amounts of money) to writing it new.

      --
      She was like chocolate when she drank... semi-sweet at first and then increasingly bitter.
    3. Re:Love refactoring but primary problem is legal by dubl-u · · Score: 2, Interesting

      Refactoring code is like paying off debt.

      Agreed! And that's the best way to explain it to execs.

      On a new project, you refactor to keep debt low. On a legacy project, you refactor to keep "interest" costs low. The interest on technical debt comes out as less reliable systems, buggier code, increased maintenance cost, and higher costs for new features. All of those cost cash money, which in my experience is a lot more money than you'd pay to do things right.

    4. Re:Love refactoring but primary problem is legal by Maxo-Texas · · Score: 2, Interesting

      Refactored code is existing code maintained. It is not legally new code. Microsoft has big lawyers but they probably have to track their software the same way every company I've ever worked for in the last 25 years has. New code is like buying a new truck. Refactored code, bug fixed code, etc. is like fixing the truck or spending extra time tuning it up. You do not get the tax benefits.

      I'm not sure where "reusable" code falls in this mix. Here you reuse existing code for a new project.

      --
      She was like chocolate when she drank... semi-sweet at first and then increasingly bitter.
  4. A problem with 'refactoring' by w3woody · · Score: 4, Interesting

    At several places where I worked management was always happy to allow cycles to be spent on the process of 'refactoring' the code.

    Unfortunately, in my experience, the process of 'refactoring' involved making code more complex by adding to it. In one case, I saw the product of the 'refactoring' process wrap two pieces of functionality into two separate EJBs (with a whole 'dto-pojo' conversion scheme for data "isolation"). In another, I saw some functionality wrapped into a collection of beans--which was later wrapped in another layer of beans, and so forth, until 20 lines of code which set up a call into the javax.xml.translate package (for performing an XSLT transformation) into something like 8 bean layers. The 20 lines of code was at the heart of an 8-layer onion, each layer added by someone else's "refactoring" operation.

    In Java, because modern IDEs allow you to write code without thinking, the problem with code is not that there isn't enough code (to prevent incestuous classes from being overly familiar with each other), but that there is too much code as programmers unfamiliar with the problem decided to add beans and interprocess communication and multiple threads without properly sizing the problem. (Right now I'm looking at an internal system which may need to process 1 transaction a second, tops, built in an inter-cooperating network of 8 EJBs, which someone thought would help improve transactional performance. Eight? A second system essentially replicates an in-memory SQL system rolled in-house: the system has been buggy because the reverse index processing had a race condition. Um, why wasn't that built in a dozen classes on top of MySQL instead of built with a couple of hundred classes that reinvent the wheel poorly?)

    While I'm glad someone wrote a book on refactoring methodology, in my experience what we need is a book which describes how to write "simple" code: code that is just as complicated as it needs to be, and no more. And a book which also describes how to simplify overly-complicated code, how to pick simpler techniques, and how to manage programmers who have an "itch" so they go scratch it somewhere else--I think that would be a much more useful book.

    It's easy to add complexity. It's hard to simplify.

  5. Re:Old news. by $RANDOMLUSER · · Score: 3, Interesting

    It is a really good book. It got me thinking about objects in ways that GoF never did. Maybe it's time to introduce a new generation of /.ers to it.

    --
    No folly is more costly than the folly of intolerant idealism. - Winston Churchill
  6. Re:Change, we love it! by magical_mystery_meat · · Score: 3, Interesting

    If the application is "done" and no major components are to be added, then by all means leave it alone.

    However, most systems aren't like that. They need to be changed due to changes in requirements, new functionality, business rules, etc., and that's where refactoring helps you - it helps isolate functionality and help the system evolve. (The app should have been designed with that in mind from the beginning, but you and I both know that it never is.)

    The main problem I have with refactoring (both the book and the concept) is that it's way too easy to go overboard with it because it presents a Right Way of writing code. Sometimes methods need to be 20 lines, sometimes classes need to do more than one thing, sometimes inheritance just gets in the way. Fowler respects these ideas, but I've known people who read this book and take refactoring to its logical extreme, which results in overly fragmented code.

    I also despise the XP directive to not comment code, which Fowler promotes.

    In all it's a good book but it's best to read it when after you've had a few years of real world experience and you can tell what should and shouldn't be taken seriously.

  7. Refactoring by jamie(really) · · Score: 2, Interesting

    There's lots of posts about how Refactoring is a waste of time, broke something or leads to bad code. I would put it to you that taking a saw and a hammer, one can do a lot to damage a perfectly good house. On the other hand, they can be used to build a nice new deck. I imagine that since I have no experience with a hammer that I would do a lot of damage. Why does everyone with no experience at Refactoring, and who tries it with poor results, assume that Refactoring is bad?

    What to about this? Some options:

    1. Quit and join a company with an established Agile practice.
    2. Form a small team to develop some new small product unit using Agile practices.
    3. Work on a small project at home using Agile.
    4. Read Feather's Working with Legacy Code and tough it out.

    Refactoring (properly) leads to improved productivity and contentment, but learning any tool requires more than reading a book.