## Session 3

### Agile Theme: The Four Variables

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.

### Refactoring Exercise, Part 1

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.

• The statement() method is long. We could factor out several helper methods. (I noted that comments are markers for a few good helpers.)
• There is duplication in two if statements that compute frequent renter points.
• The case statement belongs in a different class.
• The constants in the Movie represent different types of movie.
• Tests can be refactored, too!

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.

### Refactoring Exercise, Part 2

Do it.

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 you move code to a method, you have to handle local variables carefully, whether they appear only in the moved code or both in moved code and in remaining code.
• Pairs do more than write code together. Sometimes, one person teaches the other. Other times, both people are learning together -- talking, asking, and explaining. You were learning about the code base, but you were also learning about Ruby.
• Speaking of Ruby, we learned a little about iterators, blocks, instance variables, constants, and scope operators.
• Refactoring by hand is harder than it needs to be.

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:

• Have a reference that guides our actions as we refactor. That is precisely what Fowler's book does: it gives us a catalog of refactorings, indications of when to apply them, mechanics for how to apply them, and examples of some of the thorny issues with each.
• Have a tool that does some of the detail work of refactoring. Programming language processors such as type checkers, interpreters, and compilers use techniques that allow them to examine a program and implement some program transformations automatically. This allows them, say, to ensure local variables are created and referenced correctly.

Today's reading assignment includes a couple of refactorings from Refactoring. Next session, I hope that we will look at a refactoring browser.

### Wrap Up

• Reading. Read the Planning Game page from the original wiki. The portion up to the big image is the main exposition. The big image is useful, too. This is how we will plan our course project on Friday. Then read this short page and its link on user stories.

Read the refactoring handout (available from the department office) to help you understand some of what we did and talked about today in class.

• Programming. Study Ruby. One way to do that is...

• Homework. Work a couple of more hours on the refactoring exercise today. Improve that code in the ways we discussed in class, or in whatever ways you think worth your time. The goal is not to produce The Perfect Program but to become more comfortable with writing and refactoring Ruby code.

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.

Eugene Wallingford ..... wallingf@cs.uni.edu ..... May 13, 2010