Sponsored Link •
Martin Fowler, chief scientist at Thoughtworks, Inc. and author of numerous books on software design and process, talks with Bill Venners about design principles and the spectrum of code ownership.
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 will be published in weekly installments, Fowler gives his views on many topics, including refactoring, design, testing, and extreme programming. In Part I, Fowler makes the business case for refactoring and testing, and describes the interplay between refactoring, design, and reliability. In this second installment, Fowler discusses design principles of avoiding duplication, separating presentation and domain logic, being explicit, and describes how refactoring depends on code ownership.
Bill Venners: In your book, Refactoring you say, "The code says everything once and only once, which is the essence of good design." Why do you think the essence of good design is once and only once?
Martin Fowler: One of the things I've been trying to do is look for simpler or rules underpinning good or bad design. I think one of the most valuable rules is avoid duplication. "Once and only once" is the Extreme Programming phrase. The authors of The Pragmatic Programmer (October 1999; by Andrew Hunt and David Thomas) use "don't repeat yourself," or the DRY principle.
You can almost do this as an exercise. Look at some program and see if there's some duplication. Then, without really thinking about what it is you're trying to achieve, just pigheadedly try to remove that duplication. Time and time again, I've found that by simply removing duplication I accidentally stumble onto a really nice elegant pattern. It's quite remarkable how often that is the case. I often find that a nice design can come from just being really anal about getting rid of duplicated code.
Bill Venners: You said you've been trying to figure out the basic principles of good design. Besides once and only once or DRY, what other basic principles have you come across?
Martin Fowler: I think another good principle is separating presentation or user interface (UI) from the real essence of what your app is about. By following that principle I have gotten lucky with changes time and time again. So I think that's a good principle to follow.
Bill Venners: When you say lucky with changes, do you mean in the future it's easier to make changes?
Martin Fowler: Later on I have to make some change, and it's just a lot easier because the presentation and domain are separated. Testing also becomes easier when you separate presentation and domain logic. It's a principle that has worked very well for me. I think it makes a good base principle.
Martin Fowler: Another design principle that's struck me very firmly, particularly recently, is making things explicit. Make the code very explicitly say things.
Bill Venners: What do you mean? Could you be more explicit?
Martin Fowler: You want an example. If you're going to pass a bit of data around, do you put that data in a dictionary, and pass it around the dictionary? Or do you make a class that holds the data, and pass the data around in the class?
You might argue that the dictionary is better because you don't have to write a new class. If you need to change the data, you don't have to change any code in the dictionary. You have great flexibility in terms of what you can put into the dictionary. If you want to store a new piece of data, you don't have to change any code. You just put the data into the dictionary and give it a new key.
The problem is the dictionary isn't explicit. You don't know what keys are in the dictionary. You don't know whether to call something a customer or client. You can't tell if you make a misspelling. And above all, there's no place you can look at the code and say, "What's the interface of this thing? What are the things I can ask of it?" A dictionary is not explicit. A class, even though you have to do all the work writing in the member variables and accessors, is explicit. You can just look at that source code and know what data is present.
Bill Venners: What explicitness buys me, then, is that it is easier to understand the code.
Martin Fowler: Yes. I've been doing an IEEE software column the last year or two. I've been focusing very much on trying to identify these simple principles, and I give a couple more explicitness examples in the article, To Be Explicit (see Resources).
Bill Venners: In Refactoring you say, "I strongly believe that good design is essential for rapid software development. Indeed the whole point of having a good design is to allow rapid development."
Martin Fowler: Yep.
Bill Venners: You kind of touched on this earlier, but could you justify why you think that's the point of good design? It sounds like you're saying the only reason to have good design is to facilitate speed in development.
Martin Fowler: Yes, I think in many ways that is the case. Clarity helps you see what's in your code. You can make changes more quickly. It's harder for bugs to hide, because bugs are easier to see when the code is better designed.
Bill Venners: In Refactoring, you talk about a development team you once encountered in which each team member was publishing interfaces to others and going through lots of conniptions.
Martin Fowler: Yep.
Bill Venners: My intuition as a manager of a large team that has to build a large system, let's say from scratch, would be to first partition the system into major subsystems, then figure out the interfaces to those subsystems. And those would be published interfaces to some extent.
The interfaces wouldn't necessarily be unchangeable. Interfaces start out very changeable. Over time, they become become less and less changeable. One reason is simply the interfaces mature over time. But also, over time more code becomes married to those interfaces, and the developers become familiar with the interfaces. At some point you just have to just say, well this is the interface and move on.
Martin Fowler: You do? I don't think you necessarily need to.
Bill Venners: You eventually have to decide on an interface if you are going to publish it.
Martin Fowler: But then I argue that if you've got a team, why publish interfaces internally? To me the distinction between published and public, which I describe in another IEEE article (see Resources), is that I can't go and change the calling code of a published interface. I may realize the name of a public method isn't very communicative of what it does, that a different method name would communicate more clearly what it does. If I can find all the code that calls the method, even though it's a public method, I can change its name. In which case, I should. Published is when you can't do that. The problem in the three-person example was that they were publishing when they didn't need to.
Sun must publish its APIs. There's no way Sun can decide
List isn't a
good name, and they'd rather call it
VariableArray. It's just not something
they would want to do, because there's all that code out there relying on the name
List that Sun can't touch. But on the other hand when you've got a
development team, even with 20 or 30 people, it's not necessarily difficult to change a
name that isn't well chosen. You can change names, particularly if you've got refactoring
tools like IntelliJ or Eclipse (see Resources) that will change all the calling code for you
at the click of a mouse. It's no big deal at all.
Bill Venners: One of the other things you say in Refactoring in that same breath is, "This kind of thing you see in companies that have a strong sense of code ownership." What does code ownership mean, and what is bad about having a strong sense of it?
Martin Fowler: The way I look at it, there are three styles of code ownership. There is the XP style, which is sometimes referred to as no code ownership and sometimes as collective code ownership. In this style, no code is assigned to any particular person on the team. Anybody on the team can change any part of the system at any time. That's the XP approach.
The opposite end of the spectrum is strong code ownership. In strong code ownership, there's my code and your code. I can't change your code. If I want to change the name of one of my methods, and it's called by your code, I've got to get you to change the call into me before I can change my name. Or I've got to go through the whole deprecation business. Essentially any of my interfaces that you use become published in that situation, because I can't touch your code for any reason at all.
There's an intermediate ground that I call weak code ownership. With weak code ownership, there's my code and your code, but it is accepted that I could go in and change your code. There's a sense that you're still responsible for the overall quality of your code. If I were just going to change a method name in my code, I'd just do it. But on the other hand, if I were going to move some responsibilities between classes, I should at least let you know what I'm going to do before I do it, because it's your code. That's different than the collective code ownership model.
Weak code ownership and refactoring are OK. Collective code ownership and refactoring are OK. But strong code ownership and refactoring are a right pain in the butt, because a lot of the refactorings you want to make you can't make. You can't make the refactorings, because you can't go into the calling code and make the necessary updates there. That's why strong code ownership doesn't go well with refactoring, but weak code ownership works fine with refactoring.
Bill Venners: So the problem wasn't that these guys had interfaces to their subsystems, the problem was the interfaces were published.
Martin Fowler: That was the problem. They were publishing internally. If they had had weak code ownership, there would have been no problem.
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:
To Be Explicit, an article by Martin Fowler first published
in IEEE Software:
Public versus Published Interfaces, an article by Martin Fowler first
published in IEEE Software:
The Pragmatic Programmer: From Journeyman to Master, by Andrew Hunt
and David Thomas, is at Amazon.com at:
IntelliJ IDEA, a Java IDE with refactoring support:
Eclipse, an open source IDE with refactoring support:
A catalog of summaries of refactorings mentioned in the book, Refactoring:
A refactoring portal maintained by Martin Fowler contains links to refactoring tools and other refactoring sites:
Martin Fowler's links to extreme programming resources:
Articles written by Martin Fowler about XP and agile methods:
Patterns of Enterprise Application Architecture, by Martin Fowler is at Amazon.com at:
UML Distilled: A Brief Guide to the Standard Object Modeling Language, by Martin Fowler and Kendall Scott
is at Amazon.com at:
Planning Extreme Programming, by Kent Beck and Martin Fowler is at Amazon.com at:
Analysis Patterns: Reusable Object Models , by Martin Fowler is at Amazon.com at:
Martin Fowler's website contains many articles, book chapters, and other information from Martin: