In my last post I made the point that eliminating waste -- superfluous code, stale pull requests, unused cloud resources -- is a worthwhile investment every engineer should make on a regular basis. It minimizes complexity, which in turn lowers maintenance costs and reduces communication overhead. It also allows you to better focus your thinking and, assuming that you care about your work, makes you feel less guilty.
I promised you to write a follow-up post on strategies that can help to eliminate waste during software development. I stand by my word; here are five things that work great for my team at Jimdo.
According to the school of Lean Software Development, all work-in-progress code is a form of waste. An effective way to reduce work-in-progress (WIP), and therefore the amount of waste, is to break down projects into smaller tasks, and ship a single improvement or fix at a time. The benefits in regard to development and operations are profound. Here's an excerpt from one of my favorite Practicing Ruby articles:
Developing features incrementally reduces the number of moving parts to integrate on each deploy. This reduction in turn limits the number of new defects introduced during development.
When new bits of functionality do fail, finding the root cause of the problem is usually easy, and even when it isn't, rolling the system back to a working state is much less traumatic. Together, these approaches result in a greatly reduced day-to-day maintenance cost, which means that more time can be spent on value-producing work.
We try hard to work on no more than 2-3 tasks at a time. We continuously deploy small changes to production, so the number of pull requests waiting to be merged is typically close to 2-3 as well (depending on the state of our deployment pipeline). In order to deploy even bigger changes with confidence, we love to use feature flags whenever we can.
Complete it or delete it
Focus and WIP are inversely related. Focus is the ability to say "not yet," to finish work in progress before starting new things. The danger of not doing this -- the danger of saying yes to opportunity -- is that you'll load so much gold into the boat that you sink the whole thing. -- Baron Schwartz
Do you have a lot of code that hasn't been merged in months and that shows no visible progress either? Then it actually might not be that important. In fact, chances are high you aren't gonna need it anyway. Throw it away. Forget it. Move on.
If you use GitHub for development, as we do, you can easily list all branches of a Git repository that are either stale (no updates in the last three months) or that have been merged already. Get rid of merged branches immediately. If you're unsure whether it's safe to delete a (stale) branch, turn it into a pull request, close that pull request, and delete the branch afterwards. In case you change your mind, you can always go back to the pull request and restore the branch. This is also the reason why it's okay to close pull requests ruthlessly.
Write less code
Arguably the most efficient way to avoid waste is to not produce it in the first place. Or to put it in other words: the best code is no code at all. Atwood writes:
Every new line of code you willingly bring into the world is code that has to be debugged, code that has to be read and understood, code that has to be supported. Every time you write new code, you should do so reluctantly, under duress, because you completely exhausted all your other options.
And this is what the Lean Enterprise book has to say on the topic:
At first, we should propose solutions that don't involve writing code [...] Software development should always be a last resort, because of the cost and complexity of building and maintaining software.
Only spend time and effort on test automation for products or features once they have been validated. Test automation for experiments is wasteful.
Our most productive people are those that find ingenious ways to avoid writing any code at all.
We aren't ingenious super programmers. But we always ask ourselves whether writing code is the best solution to a problem. More often than not there are good alternatives, including:
- Outsourcing the task to a third-party library or service.
- Measuring whether or not investing in some code is worth the effort.
- Ignoring the problem because it will go away in the foreseeable future.
Get it out of your head
There's only so much information that any of us can absorb and retain. Whenever something pops up in your mind, something that you cannot do right away, get it out of your head. Write it down, open a ticket, add it to your to-do list. However you do it, it's important to keep track of outstanding tasks. This is true for feature development, but even more so for cleanup tasks which tend to be forgotten.
This strategy also happens to be at the heart of Getting Things Done, the popular time-management method by David Allen:
The entire GTD methodology is centered around that feeling: that the more tasks and ideas you get out of your head, the more attentional space and mental clarity you'll have throughout the day. Particularly after you break down your big, ugly tasks and projects into their logical next steps.
We're currently using digital Kanban boards to organize our work and track milestone progress. The boards and tickets are stored in Trac which, although cumbersome and slow, gets the job done for now.
On a related note, it might also be a good idea to document cleanup tasks as source code comments. Here's an example from our codebase:
// XXX: #86020 WEBCACHE META ITEM MIGRATION // you may remove me after January 2016 ... some PHP code ...
By referencing the original Trac ticket, we add context for other developers -- and our future selves.
Work in pairs
Pair programming yields many benefits. In fact, there are so many benefits that I'm going to write a separate post on the subject. For now it's enough to say
that pair programming works great for our team and we're happy with the results. Above all, it has helped us to reinforce all the habits I shared with you today.
This is what works for us. I'm sure there are other strategies that work for your team. Feel free to share them in the comments below.
Acknowledgements: All quotes from "Lean Enterprise" are based on tweets by my coworker, Soenke. The witty phrase "complete it or delete it" was shared on Twitter by Kent Beck. The cover photo is from Flickr.