I ran a race this past weekend. It gave me lots of time to think about ultra-running and some of the lessons I've learned and how they can apply to software development. I've written before about breaking things down into smaller chunks, but I had a little new insight into that this weekend.
Take Things One Step At A Time
A large race can be overwhelming. An easy strategy to help combat that feeling of overwhelm is to break the race into smaller chunks. A convenient breakpoint is each aid station. In a longer race there is an aid station every 5-10 miles. As you leave each aid station, you only have 5-10 miles to the next aid station. It's easy to wrap your head around that. It's similar to a normal training run.
Context Is Still Important
You can treat each section as a normal training run. However, it's not quite that simple. If you really want to be successful, you need to treat each section differently depending on the context.
Each section has an inherent context. These are things like: the length of the section, elevation gain/loss, and surface conditions. Each of these changes how you attack that particular section. A 7-mile run downhill on a nice smooth surface is very different from a 5-mile run up a steep rocky hill.
The environmental context is the immediate conditions. This includes things like time of day, weather, and trail conditions. The same 5-mile section of the trail requires a different approach if it is dry and hot out, versus if it is cool, wet, and muddy.
Big Picture Context
Perhaps the most important context is the overall race itself. What is the overall strategy I am trying to achieve? Is my plan going out fast and just holding on? Am I trying to run negative splits? Am I trying to walk the hills and run everything else? Timing also matters in terms of is this section at the beginning of the race when I am nice fresh or at the end when I am tired? Am I about to miss a cutoff? The answer to all these questions influences how I attack a particular section.
Software Development Has Context As Well
Software Development also has a context. It doesn't happen in a vacuum. There are a lot of factors that influence how we write a particular piece of code.
The inherent context is really all about the tactical task at hand. What exactly is the low-level goal of this particular piece of code? If I were writing a unit test, what would it be testing? What part of the code am I working in? Is it the UI, the database, or a web service? How familiar am I with the technology and that particular task? How confident am I that I can solve the problem? If I am unfamiliar or the change seems risky, I'll take a lot smaller steps than I would if it is something more routine.
Environmental context is about the type and lifecycle stage of the project. How urgent is this particular task? It also involves the state of the project. Is this a new project or prototype? or is it an established project? If it's a new project, I'll be making lots of changes so I may make some larger commits where I add whole new modules. If it is an established project, I'll be more concerned about breaking things, so I'll make smaller more targeted commits.
Another architectural context is our team expectations. What is expected in terms of code review, style, unit tests, and documentation? How is the program architected? As an example, if I asked you to write a timer, you could use a class, an FGV, a DQMH Module, or an AF module. Which one you choose would probably depend on the architecture of the program and the competency of your teammates and what techniques they are familiar with.
Big Picture Context
For software, the big picture context is all about the human side of a project and our business goals. The first and most important goal is to better the lives of our users and make sure we take care of all the other people involved in the project. This one is first because if we do this, it leads to the business goals. If we do it the other way around, it doesn't always work out. The business goals are certainly important and any project has to be financially viable, but that has to be the byproduct of taking care of the people involved. So we always have to keep the needs of our users and the business in mind even as we are working on taking these smaller steps.