I run a fair amount these days, train to get faster, and run races from 5K to marathon in length. ... I have long set a personal goal that my usual time at a particular distance be < 2 * the world record at that distance. This is tougher at some distances than others, because the pace of the fastest runners at each distance is different. This chart is from 2004, but it shows the idea:
As a child, I didn't understand this. I thought that the way to be faster longer was to train by running one step farther each day at the target pace. Eventually, I'd run a mile at the same velocity as my best 50m! No limits.
But that chart has that shape for a reason: there is a trade-off between speed and distance in the product category "world's fastest runner". If you want a runner to maintain a faster speed, then you will have to give up distance. If you want a runner to maintain a speed for a particular distance, then you will have to accept a slower speed. This is true of the world's fastest runners -- who set the upper bound on expected performance for the rest of us -- and it is true for other runners, too.
This is a variation in theme on the famous Heisenberg Uncertainty Principle. For runners, it's not so much about the uncertainty as about the trade-off.
This applies to software development, too. Speed vs distance == time vs scope. Kent Beck has argued that there are four variables at play: time, scope, cost, quality. Software developers and clients often try to control all four of these at the same time, independent of each other. But we can't do that, because there are natural trade-offs among them. If you want to get done sooner, then you'll need to do less, spend more money, or produce a lower-quality product. If you want to spend exactly X dollars, then you'll have to work a limited number of hours, do less, or produce a lower-quality product.
For Beck, the Heisenberg Uncertainty Principle really is at play, in its full force. You can fix values for three of the variables, but then you must recognize that you won't be able to predict the value of the fourth variable very well! Which one of these four items are you as a developer willing to sacrifice? Which one do you think clients are most willing to sacrifice?
Beck isn't the first to write about this. In The Secrets of Consulting, published in 1985, Gerald Weinberg talks about the necessity of recognizing trade-offs and making them explicit in the projects one does. Whenever the client asks for some optimal something -- the minimum cost solution, the shortest possible time, the best possible way -- the wise consultant asks, "What are you willing to sacrifice?"
(Note: I originally posted a version of this on my blog back in July 2004.)
... planning game, sustainable pace, TDD, refactoring.
Take a look at this small code base, which is part of the information system for a movie rental store. This code is from adapted from Martin Fowler's book Refactoring: Improving the Design of Existing Code. David Koontz typed up the original version from the book, in its original Java form. I ported it to Ruby for just for you. The code is also available as a zip file.
Figure out what the code does, and how. It has tests that illustrate several common use cases.
How would you improve this code? What smells bad, looks bad, feels bad? What about the code got in the way of your understanding it more quickly?
Some of your ideas:
Excellent suggestions. As object-oriented code, this program leaves a lot to be desired. You have identified several changes that we commonly make when improving (OO) code, including Move Field, Extract Method, Move Method, and Replace Conditional with Polymorphism.
Pair up with someone you have not paired with. Swap driver and navigator every so often. Select a small improvement to make, make it, and run the tests to ensure the program still works. Then select another... Take small steps.
Some things we observed:
When I learn a new code base, I often refactor it to reflect my growing understanding of the code.
So, refactoring by hand is harder than it needs to be. Wouldn't it be nice to have support? I can think of two kinds of support, in addition to pair programming:
Today's reading assignment includes a couple of refactorings from Refactoring. Next session, I hope that we will look at a refactoring browser.
Read the refactoring handout (available from the department office) to help you understand some of what we did and talked about today in class.
By class time tomorrow, send me a zip file containing your improved code. Be sure to include a readme.txt file that lists and perhaps explains the changes you made.