Thursday, February 19, 2009

When I was first introduced to Unit Testing, I didn't like it because it was doing things to my code that I didn't like. Over time I realized that it was my code that was the problem and not the tests. I seem to be in that same place again with wanting to continuously delivery working software without the artificial boundaries of iterations and releases. Where you make very thin slices of your tasks and deliver a slice when its done. Where every commit is also a deploy.

Wednesday, February 18, 2009

For some, estimates serve as targets. Targets set the pace at which work gets done. They change one's relationship with time (you get a lot more work done on the day before going on vacation than on a regular day).

A surprising finding was that, in a controlled experiment, the subjects who had no schedule at all finished their project first, beating out both the group that had an aggresive schedule and the one that had a relaxed schedule. Experiments have shown that engineers, in general, are good at achieving the one tangible goal that they have been given: If the primary goal is to finish according to a given time schedule, they usually will-but at the cost of other goals such as clarity of documentation and structure.

Sometimes we set targets in order to convince others, or ourselves, that something can be done. We may set targets to inspire ourselves to do more, though it’s not clear that’s a winning move, and even less so when managers set a target to “inspire” the folks who work for them. (See DeMarco and Lister’s Peopleware, chapter 3 and the discussion of Spanish Theory managers.) We may also set targets to give ourselves a feeling of control over the future, illusory though that feeling may be. After the fact, a target hit or missed can tell us whether or not we did what we set out to do. However if we missed a target, we can’t know whether that’s because the target was unrealistic or because we didn’t perform as well as we should have. Setting and hitting targets does make it look like we know what we’re doing but we need to keep in mind that targets rarely encompass all the things we care about — it’s much easier to set a target date for delivering software than a target for how much users will love it.

If the goal is simply to develop as much software as we can per unit time, estimates (and thus targets), may be a bad idea. In chapter 4 of Peopleware, DeMarco and Lister discuss a study done in 1985 by researchers at the University of New South Wales. According to Peopleware the study analyzed 103 actual industrial programming projects and assigned each project a value on a “weighted metric of productivity”. They then compared the average productivity scores of projects grouped by how the projects’ estimates were arrived at. They found that, as folks had long suspected, that programmers are more productive when working against their own estimates as opposed to estimates created by their boss or even estimates created jointly with their boss, averaging 8.0 on the productivity metric for programmer-estimated projects vs 6.6 and 7.8 for boss-estimated and jointly-estimated. The study also found that on projects where estimates were made by third-party system analysts the average productivity was even higher, 9.5. This last result was a bit of a surprise, ruling out the theory that programmers are more productive when trying to meet their own own estimates because they have more vested in them. But the real surprise was that the highest average productivity, with a score of 12.0, was on those projects that didn’t estimate at all.

Tuesday, February 17, 2009

A lot of us are uncomfortable with doubt and uncertainty. Estimation is a way for us to put a fence of certainty around the inherent uncertainty of software development. However, coming up with a date for when a task will be done, does not remove the uncertainty, it just hides it.

A key technique for absorbing changes easily is to avoiding repetition like the plague. If you have to say the same thing in more than one place – either in design documents or code – then refactor the design to consolidate the capability into one place. One of the most effective ways to facilitate change is to localize every potential change in only one place.

If small steps are how to design, the next question is where in the system to improve the design. The simple heuristic I have found helpful is to eliminate duplication. If I have the same logic in two places, I work with the design to understand how I can have only one copy. Designs without duplication tend to be easy to change. You don't find yourself in the situation where you have to change the code in several places to add one feature.

IMO, if you couple minimizing repetition with writing code that is communicative, you should be in a fairly good place.