I was reading last night on NoodleFood on the Complexity of the Conceptual Mind. Diana reposts a blog about problems of concentration. The original author starts by giving an example of how a seemingly simple task can spiral into a long sequence of related tasks. The end result of this process is often a failure to accomplish the original task. The ability to focus on long and short-term goals at the same time is a key component of project success.
Joel Spolsky has a recent post entitled Capstone projects and time management. His article begins by discussing the failure of universities to prepare students for real-world software projects, and ends with this comment:
I’ve been blaming students, here, for lacking the discipline to do term-length projects throughout the term, instead of procrastinating, but of course, the problem is endemic among non-students as well. It’s taken me a while, but I finally learned that long-term deadlines (or no deadlines at all) just don’t work with professional programmers, either: you need a schedule of regular, frequent deliverables to be productive over the long term. The only reason the real world gets this right where all-student college teams fail is because in the real world there are managers, who can set deadlines, which a team of students who are all peers can’t pull off.
Regular frequent deliverables? That sounds like the agile value of short iterations to me. What’s important here is that two separate needs of the human mind are met by small processes. The first is a need to see how what you’re doing fits into the larger project or task you’re trying to accomplish. The second is to aid your ability to concentrate on the task at hand.
I find this discussion of time-management to be very interesting. Since I’ve adopted agile programming methodologies, I’ve noticed an increase in my productivity. Some of the productivity gains stem from my increased mastery of good design practices. But I think the major factor is my focus on short deliverable iterations. Writing unit tests is a way of maintaining the context of what I need to get done. Often I’ll be writing a test for feature-A, which I’ll discover depends on feature-B that I haven’t written yet. I can stop working on test-A and go write feature-B, building tests for feature-B as I go. When I’m done with feature-B, I still have the failing test for feature-A to remind me what remains to be done. On a day to day basis, the tests allow me to branch into sub-tasks at will without too much mental strain. TDD, in addition to its other virtues, is an aid to concentration.
Disciplined refactoring can also be an aid to concentration. In Martin Fowler’s Refactoring: Improving the Design of Existing Code, he discusses in detail many of the ways code can be changed. He starts with examples as simple as renaming a variable. Over the course of the examples, it becomes clear that larger refactorings are composed of smaller ones. The main takeaway for me was that in order to be successful with large refactorings, I have to break the task into smaller ones and complete each small refactoring before moving on to the next one.
For example, let’s say I need to split a class into two smaller classes. I can introduce the new class and immediately move all members from class A that I think belong in class B. If I do this, I’ll immediately break large pieces of the system. I’ll have to deal with all the various compile-errors and redirection points all at once, and this before I have a chance to verify that this is really what I want to do. On the other hand, I could create class B and begin my exposing it as a property of A. I could then move one property or method at a time from A to B, correcting the compile-errors as I went. When I have A an B looking the way I want I can simply remove the property from A, completing the separation.
Again, at any time during the refactoring it is only necessary to be attentive to a few issues at once.
Long Term Tasks
Not every task can be finished in a few hours. For longer-term tasks I have to break my work into milestones that are meaningful to me. I’ve started using an online tool called Zen to keep track of these things. I discovered agilezen in a recent .NET Rocks episode. I’ve been using it for awhile now and find it to be exactly what I need to keep track of the larger details of my work.
To run a successful project you must break long-term goals into shorter-term goals. This is for the same reason that a successful architecture requires that you break your project into smaller components, components into smaller classes, and classes into smaller functions. Software development is like any other task in life. You have to adapt your development and task-tracking methods to facilitate success. There’s only so much you can hold in your mind at once, but agile development methods allow you told tend the trees as you grow the forest.