I enjoy reading Bill Venners’ interviews with software development luminaries. Bill himself is (from what I’ve seen) a talented and tasteful developer, and he picks some of the best to interview. Plus, he makes sure he’s familiar with each person’s work, and asks intelligent questions. This week I read the final part of his interview with Martin Fowler, and it really resonated with some lessons I’ve learned over the past few years.
Last year I gave a talk at JavaOne (and later for two other audiences) called Stalking Your Shadow: Adventures in Garbage Collection Optimization. (Although it sounds like an arcane optimization talk, in reality it’s sort of a “stealth agile” talk—the firmest recommendation in it is to do tightly iterative development with performance testing beginning very early in the process, so you can catch poor decisions early, while they’re easy to change.) In that talk, I point out that the right optimization strategies are strongly dependent on your choice of platform, that different optimization strategies might either conflict with each other or reinforce each other, and that you must measure the effect of your changes to see whether they help or hurt performance.
The implication there, of course, is that if you are thinking about multiple optimizations in your system, then you must—if you want to avoid what Mike Clark calls “thrash tuning”—-have ways to mix and match those optimizations as you measure, to see which combination produces an acceptable result. One trick I recommend is to implement each of your optimizations as aspects using AspectJ. AspectJ makes it very easy to choose, from build to build, which aspects are included in your system.
I was focusing on optimizing at a particular point in time, but Martin talked to Bill Venners about the ongoing lifecycle of software. He discusses how advances in platform implementation technology can turn today’s optimizations into performance drags (he’s talking specifically about VMs, but the same things apply to the OS and compiler). He recommends that optimizations be revisited with each platform upgrade. To do that, of course, you need to keep the design simple and the optimizations well encapsulated.
My strategy of using AspectJ to insert the optimizations from the outside could make this a breeze. Start with the clean design, and after profiling you can leave the clean code in place, but replace it using an aspect that implements the optimization. Later, you can easily build with optimizations included or excluded and run your performance tests again.
(This also reminds me of a story I’ve heard several times about the development of Microsoft Excel. They have a very simple evaluator that they are certain is correct, but it’s very slow. They also have a completely separate, highly optimized and fiendishly complex evaluator. During development and testing they run it with both evaluators turned on, with the simple, slow evaluator checking the work of the fast one. Then they turn the slow evaluator off for the production build. This strategy seems to work well—I’ve certainly encountered numerous bugs in Excel, but none have involved the evaluator, and evaluation is fast.)
At any given moment, I’m in the middle of more than one book. I just tend to get fiercely interested in something else before I finish with one book, so I go off on a tangent for a while with a new book, eventually coming back to finish the first.
About a week before Christmas I was rereading Neal Stephenson’s The Diamond Age. It’s a really interesting book, in part because of its form: it is quite definitely a science fiction novel, but it is structured as a Victorian novel, complete with the distinctive chapter headings: a little graphical ornament, and a short synopsis of the events that will happen in the chapter.
Then I spent a lunch break at the bookstore, and came across a book I’d heard many good things about: To Say Nothing of the Dog, by Connie Willis. Based on universally good reviews, I’ve been wanting to read it for a few years, and I was in a hurry, so I just snatched it from the shelf and bought it on an impulse.
Lo and behold, it’s another Victorian science-fiction novel. Without planning it, I find myself in the position of simultaneously reading two Victorian science fiction novels. There can’t be too many books that fit that description; what an interesting coincidence.
I’ve had a couple of weeks off from work, and I spent it mostly away from my computer, doing things with the boys, having a relaxing time.
Not that I haven’t been thinking about topics I wanted to blog. In fact, I’ve got a whole list of observations about the several wonderful books I got from Christmas; I’ll be blogging them over the next few days under the overall title “Christmas Books.”
I have a strong preference for simplicity in software, and I’m frequently frustrated by people who seem to value complexity instead, and who don’t seem to understand why the simpler solution is usually preferable.
But I shouldn’t be so hard on them, I guess, because it’s all a matter of degree. There are designs that are too simple for me to really grasp. And I don’t mean designs that are too simple to work; I mean designs that seem too simple to me, because I don’t understand how the simple solution meets all the needs. Want examples? Take a look at nearly everything Ward Cunningham does.
FIT is the latest thing Ward has blown my mind with, but it’s certainly not the first:
- I’m sorry, but how could the WikiWikiWeb ever work? This simple little web site, with a trivial formatting language, where you create new pages just by linking to them, and you link just by SmashingWordsTogether, and anyone can edit the entire text of any page at any time. But it does work, and it created a vibrant community of mostly like-minded software developers. It makes a terrific discussion tool for teams of almost any size.
- Last year at OOPSLA, Ward helped run the workshop on Software Archaeology. His position paper floored me. He presented perhaps the most useful tool discussed in the workshop, and it’s one that he wrote himself in less than a hundred lines of Perl.
- Also last year, after Bob Martin and Robert Koss used the development of a bowling score program to illustrate the process of pair programming, several people in the XP community used the same example to illustrate other parts of the process, and different programming techniques. Ward’s solution was unique in its approach, and the only thing that makes it at all difficult to comprehend is that it’s written in a rather unnatural style of Perl. (Ward used Perl’s regular expression operations to simulate an APL-ish style of problem solving.) Once you get past that, it’s breathtakingly simple.
I’m embarrassed to say that I would never have tried any of those approaches to those problems, because they would’ve struck me as naive. But I would’ve been wrong.
The funny thing is that, as folks have mentioned FIT to me over the past few weeks, all of them have said something like this: “It’s a little mind-bending, but knowing Ward, I suspect the problem is with my mind, not FIT.” That’s exactly how I feel. It’s good to know I’m not alone in that.
It’s been a while since I subscribed to the XP mailing list, but I manage to hear about most of the important developments, I think. A few weeks ago, Dave Thomas told me about FIT, Ward Cunningham’s Framework for Integration Testing.
It sounded intriguing, but I really didn’t have time to investigate it. Then, at the Lone Star Software Symposium in early November, Daniel Steinberg mentioned FIT and how interesting it is. And last week, Mike Clark sent me a draft of some early work he’s done with FIT. By the rule of three, then, I suddenly had to spend the time on it … when three people of that caliber are talking about something, it deserves attention.
And FIT does deserve attention. Ward designed it to address one of the more difficult parts of Extreme Programming: the idea that customers should specify—and ideally write—automated acceptance tests. FIT is a fascinating approach to that problem. Naturally, the programmers must help, but they help in very small ways; primarily by writing tiny, simple adapter classes that hook application objects into FIT.
FIT is still in the early stages, and there are numerous problems to be solved. But it has the potential to work really well, at least partly because it is simple and adaptable rather than feature-complete and all-encompassing. If you haven’t looked at it and played with it, make the time to do so.