Over the last decade, Martin Fowler pioneered many software development techniques in the development of business information systems. He's well known for his work on object-oriented analysis and design, software patterns, Unified Modeling Language, agile software processes (particularly extreme programming), and refactoring. He is the author of Analysis Patterns (Oct. 1996), Refactoring (June 1999; coauthored with Kent Beck, et al.), UML Distilled (Aug. 1999; with Kendall Scott), Planning Extreme Programming (Oct. 2000; with Kent Beck), and the soon to be released Patterns of Enterprise Application Architecture (Nov. 2002), all published by Addison Wesley.
In this six-part interview, which is being published in weekly installments, Fowler gives his views on many topics, including refactoring, design, testing, and extreme programming (XP). In Part I, Fowler makes the business case for refactoring and testing, and describes the interplay between refactoring, design, and reliability. In Part II, Fowler discusses design principles of avoiding duplication, separating presentation and domain logic, being explicit, and describes how refactoring depends on code ownership. In this third installment, Fowler differentiates between planned and evolutionary design, suggests that focusing on superficial problems can lead to the discovery of substantial problems, and claims that doing a good job won't slow you down.
Bill Venners: In your paper, "Is Design Dead?", you talk about planned design. What is planned design?
Martin Fowler: I distinguish between planned and evolutionary design. Planned design says that when you think about a piece of software, you create the design first, then you code it. A planned design could take the form of UML diagrams. Or you could express it in terms of dividing a system into subsystems and defining the interfaces between those subsystems. With planned design, there's a definite switch between the two modes of creating the design and then coding it. And those tasks may often be performed by different people. Architects come up with design. The developer then code it. The design is not necessarily considered completely fixed, but it is considered mostly fixed. You can argue that the better the design, the less it will change as you code it.
With evolutionary design, you expect the design to evolve slowly over the course of the programming exercise. There's no design at the beginning. You begin by coding a small amount of functionality, adding more functionality, and letting the design shift and shape.
The point I make in "Is Design Dead?" is that most people have encountered evolutionary design in an unconstrained and ill-disciplined environment and it doesn't work. You end up with a crappy design. And that's one reason why people gravitate towards planned design.
But in my view, extreme programming's practices of continuous integration, testing, and refactoring actually make evolutionary design work, and more effectively than planned design. Planned design's weakness is that creating a well-planned design is actually really tough.
Bill Venners: Why?
Martin Fowler: I don't know. Why is composing symphonies tough? I don't know. It's just very few people in the world can do it well. And I think that's the case with upfront design. It is very hard to do well.
It's interesting that many of evolutionary design's major proponents, like Kent Beck and Ward Cunningham, are stunningly good designers. But they came to the conclusion that their upfront designs were often not very good. They tended to over-engineer things, adding unnecessary complexity to their designs. They would often make a design flexible in areas that didn't need flexibility and inflexible in areas that did need it. So they've adopted an approach where, by applying a set of disciplines, evolutionary design works instead. As a result, they have created better designs, and at a faster rate. I think 80 percent of the time evolutionary design works for me as well. And I have the arrogant opinion that I am an above average designer, so I think evolutioary design would be even more useful for a wider range of people.
Bill Venners: How does refactoring change the role of upfront design?
Martin Fowler: The reason you do planned design is because you think it's too hard to change the code. Because when you change the code, you break things and introduce many bugs. However, if you have both unit tests and build the disciplined technique of refactoring on top of the tests, you can make changes much more efficiently and faster, and you're much less likely to introduce defects.
Bill Venners: What is the role of upfront design in the context of refactoring and the other enabling practices? Do you still do some upfront design?
Martin Fowler: I think there's still room for some upfront design, but not a lot. People like Kent Beck and Ron Jeffries say it is eliminated. In a way they are right; you could build even a complex system purely through evolutionary design. But there are cases where you'll go faster with some upfront design. So I would disagree with the idea that you don't put your database in before you evolve your need for a database. I would make an initial decision about the presence of a database and go from there, but I would still evolve most of the design.
Bill Venners: Is there a difference between a well-factored program and a well-designed program?
Martin Fowler: There really isn't a difference in terms of what they are, but maybe in terms of emphasis. Design is about factoring--dividing a program into well-separated parts. To me, well-factored conveys more about what the design feels like when you are looking at it or working with it.
Bill Venners: To explain when to apply refactorings, you write in your book Refactoring: "Rather than appealing to some vague notion of programming aesthetics (which frankly is what we consultants usually do), I wanted something a bit more solid."
I'm curious to what extent you think aesthetics matter. In most of my experience, I've had to work with an already existing body of code. The code is usually poorly designed, and as a result, very painful to work with. I would really appreciate a good design that isn't so painful to work with. So aesthetics matter to me at least in the sense that well-designed software makes my work life more enjoyable.
Martin Fowler: I wrote that about aesthetics in discussing when you apply refactorings. To some extent, the situations I describe in the refactoring guidelines are fairly vague notions of aesthetics. But I try to provide more guidance than just saying, "Refactor when the code looks ugly." I say, for instance, that duplicated code is a bad smell. I say that long methods are a bad smell. Big classes are a bad smell.
Many bad smells can be very superficial. When you look at a program, it is amazing how often focusing on some superficial element, like a 100-line method, can help you improve a design.
In the course of refactoring a 100-line method, you find that some bad design decisions were made about responsibility allocation. You couldn't spot the bad design decision just by looking at the method, but you could spot that the method was 100 lines long. And the superficial problem led you to the rest of the mess.
Bill Venners: I once worked on a project where there was an 11-page while loop.
Martin Fowler: That's appalling.
Bill Venners: And it was still 11 pages after our 6-month task force to stabilize the software, because we were afraid to change it.
Martin Fowler: That itself indicates the 11-page while loop's bad design, because if you're afraid to change something it is clearly poorly designed.
Bill Venners: I think one problem with getting people to care about design is that people change jobs. The developers who originally created the 11-page while loop had left the company by the time we had to clean it up. I think often programmers figure the chances they will actually experience the pain of dealing with their bad designs are slim, so they don't necessarily have an incentive to care. And even if a programmer does care, design is still hard to do well. Good design takes time, and it seems like there is always time pressure.
Martin Fowler: I don't agree that it takes longer to create well-designed code.
Bill Venners: Why not?
Martin Fowler: It is a curious thing. We seem to have a notion in the software industry that doing a good job slows you down. And yet when I think about working to keep code well-factored and writing tests, I find that makes me go faster.
I think people look at the time spent cleaning up a design as lost time. They don't see the time they gain when they change the code later and it is so much easier. It only takes a few minutes to make the change when it otherwise would have taken a couple hours.
People also underestimate the time they spend debugging. They underestimate how much time they can spend chasing a long bug. With testing, I know straight away when I added a bug. That lets me fix the bug immediately, before it can crawl off and hide. There are few things more frustrating or time wasting than debugging. Wouldn't it be a hell of a lot quicker if we just didn't create the bugs in the first place?
Refactoring: Improving the Design of Existing Code, by Martin Fowler with Kent Beck, John Brant, William Opdyke, and Don Roberts is at Amazon.com at:
http://www.amazon.com/exec/obidos/ASIN/0201485672/
To Be Explicit, an article by Martin Fowler first published in IEEE Software:
http://www.martinfowler.com/articles/explicit.pdf
Public versus Published Interfaces, an article by Martin Fowler first published in IEEE Software:
http://www.martinfowler.com/articles/published.pdf
The Pragmatic Programmer: From Journeyman to Master, by Andrew Hunt and David Thomas, is at Amazon.com at:
http://www.amazon.com/exec/obidos/ASIN/020161622X/
IntelliJ IDEA, a Java IDE with refactoring support:
http://www.intellij.com/idea/
Eclipse, an open source IDE with refactoring support:
http://www.eclipse.org/
A catalog of summaries of refactorings mentioned in the book, Refactoring:
http://www.refactoring.com/catalog/index.html
A refactoring portal maintained by Martin Fowler contains links to refactoring tools and other refactoring sites:
http://www.refactoring.com/
Martin Fowler's links to extreme programming resources:
http://martinfowler.com/links.html
Articles written by Martin Fowler about XP and agile methods:
http://martinfowler.com/articles.html#agile
Patterns of Enterprise Application Architecture, by Martin Fowler is at Amazon.com at:
http://www.amazon.com/exec/obidos/ASIN/0321127420/
UML Distilled: A Brief Guide to the Standard Object Modeling Language, by Martin Fowler and Kendall Scott is at Amazon.com at:
http://www.amazon.com/exec/obidos/ASIN/020165783X/
Planning Extreme Programming, by Kent Beck and Martin Fowler is at Amazon.com at:
http://www.amazon.com/exec/obidos/ASIN/0201710919/
Analysis Patterns: Reusable Object Models , by Martin Fowler is at Amazon.com at:
http://www.amazon.com/exec/obidos/ASIN/0201895420/
Martin Fowler's website contains many articles, book chapters, and other information from Martin:
http://www.martinfowler.com/
Have an opinion? Be the first to post a comment about this article.
Bill Venners is president of Artima Software, Inc. and editor-in-chief of Artima.com. He is author of the book, Inside the Java Virtual Machine, a programmer-oriented survey of the Java platform's architecture and internals. His popular columns in JavaWorld magazine covered Java internals, object-oriented design, and Jini. Bill has been active in the Jini Community since its inception. He led the Jini Community's ServiceUI project that produced the ServiceUI API. The ServiceUI became the de facto standard way to associate user interfaces to Jini services, and was the first Jini community standard approved via the Jini Decision Process. Bill also serves as an elected member of the Jini Community's initial Technical Oversight Committee (TOC), and in this role helped to define the governance process for the community. He currently devotes most of his energy to building Artima.com into an ever more useful resource for developers.
Artima provides consulting and training services to help you make the most of Scala, reactive
and functional programming, enterprise systems, big data, and testing.