The Mindful Programmer: Meditations on Work Processes
As programmers, we believe new frameworks and languages can make us more productive. But how we do that matters too.
Join the DZone community and get the full member experience.Join For Free
As programmers, we believe new frameworks and languages can make us a lot more productive. We read books, watch online courses, and go to hackathons. Of course, these things matter. But I believe the way you do your work, the process itself, can have a great impact on your productivity than any framework or language.
This article talks about two techniques I use to improve my process: labeling and daily retrospectives.
Note, I am not trying to convince you to start following my work process. You probably already have one that works best for you. My work process is just an example of something I have been doing for years, without fully understanding it. Labeling and daily retrospectives helped me lift it from subconsciousness to consciousness, which made it much more powerful.
When tasked to build a feature I go through the following five steps:
- Building Foundation
- Implementing Feature
- Cleaning Up
Spiking: Building First Scenario Top-Down
First, I try to come with a set scenarios that fairly accurately describe the feature. If the client provided those–great. If not–I have to come up with those on my own.
I pick the scenario illustrating the feature the best. It does not have to be the easiest one, nor it has to be the most complicated one. Just something that will give me a good enough idea of how the feature should be implemented.
I write an acceptance test. And then, in a top-down fashion, I go through the system doing the minimum amount of work required to make the acceptance test pass. I do not refactor. I do not do TDD. I do not care about good names. I take shortcuts, copy and paste code, etc. . My objective is very simple – make the acceptance test pass.
While doing this work, I note what changes to the system are required. In addition, I write down everything I find important or interesting. The notes, not the code, are the result of this work. I always throw away the code produced at this stage.
Next, I take the notes and sketch up a few solutions/designs for the feature. I evaluate the potential designs and pick the one I believe will work best. This does not take more than half an hour.
I experimented with doing this step before spiking, but it often resulted in something so inaccurate that it was not useful, and seemed to do more harm than good.
I also find that a lot of agile-minded people skip this phase. They go right from spiking to building production code. I think this is a mistake. Stepping back and spending thirty minutes with a pen and a sheet of paper is extremely valuable.
The result of this phase is a few diagrams with some notes on the side–a fairly good plan on how to implement the feature.
Building Foundation: Building The Same Scenario Bottom-Up
I start implementing the same scenario once again, but this time bottom-up. I do it very carefully, using test-driven development. This phase is very different from the spike. While doing the spike, I tend to investigate how the code works. I fire up a debugger to see what is going on. I explore. This phase is different. I take only safe steps. If at any point, I feel like I have lost understanding of the system, and I need to debug it, I roll back and take a smaller step.
Building Second Scenario: Top-Down
After the first scenario is done and checked in, I take another one. I build it top-down starting with an acceptance test.
Why not bottom-up?
In general, I find that the top-down approach results in better design. But sometimes I find it challenging if there is not enough structure to hang the new behavior on. That is why the first scenario is built bottom-up. Doing it that way creates enough structure to attach the rest of the feature to.
So the first scenario is the only one I built twice: top-down during “Spiking,” and bottom-up during “Building Foundation.”
Throughout my work I follow “4 Rules of Simple Design” by Kent Beck:
Make Tests Pass
Remove Unnecessary Abstractions
After all the scenarios have been implemented, I go through “Fix names,” “Remove Duplication,” “Remove Unnecessary Abstractions” once again to tighten up the code.
That is the approach I use when implementing a feature:
- Building Foundation
- Implementing Feature
- Cleaning Up
Obviously, this process is simpler when fixing a small issue, and a lot more involved when actually designing a new system, where it is closer to what George Polya talks about in his excellent book “How to Solve It!”
Technique 1: Labeling
Labeling is a technique I find particularly useful for staying mindful throughout the day.
Before starting on a feature, I write down “Spike” and the objective of the spike. While doing the spike, I write down every step I take (just a word or two). When I switch from “Make Tests Pass” to “Fix Names,” I write it down: “Fix Names.” Basically, at any point in time, I can look at my notes and see my current activity written down at the bottom.
The fact that I see the current phase and step in front of me helps me stay focused. This does not mean I do less experimentation or have less fun at work. I am just aware of when I switch from the “write production code” mode to the “experimentation” mode and vice versa. Similar to how mixing refactoring and behavior code changes is usually not a good idea, experimenting while writing production code does work very well either.
The key idea here is to come up with a set of labels that concisely describe what you do. If you have to write a sentence about your every step, you will quickly stop doing it. It will also make it much harder to read.
What you want instead is something akin to red/green/refactor. The labeling scheme so simple that it uses colors instead of words.
In addition to increasing my awareness, labeling also produces the log of everything that happened during the day, which is useful during daily retrospectives.
Technique 2: Daily Retrospectives
In the evening I spend ten minutes reflecting on my day. I ask myself questions like “Have I felt productive?” or “What have I learned?” I also read through the taken notes trying to see if there anything to think about. Then, I write down my thoughts.
Once in awhile, I read through my records looking for interesting patterns. For instance, once I noticed that every time I used labeling at work, I felt like I achieved and learned more. Another time, I found that adhering to my process helped me get stuff done.
The way you do your work affects your productivity in such a way that no framework or language can. The two techniques I use to improve my work process are labeling and daily retros.
Labeling helps me stay focused on the task at hand, and as a byproduct produces a record of everything interesting that happened during my day. I review these records during daily retrospectives and make adjustments to my process.
So I ask you to look at your process. Think about all the different activities you do and assign labels to them. Use these labels to become more mindful of what you do on day-to-day basis.
Published at DZone with permission of Victor Savkin, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.