The many benefits of working in small increments

If you're a software engineer, you've likely heard of the Single Responsibility Principle (SRP). I believe it's the single most important principle in software engineering. The simple explanation is that one object should do only one thing and do it well. Having a well defined single responsibility makes code easier to understand, change, delete, and test.

The complexity of code grows exponentially with size. Two 100 line classes, with proper segregation of responsibility, are significantly easier to understand than a single 200 line one. SRP is the "work in small increments" principle for code, and the same exponential growth in complexity applies to much more than just code. Working in small increments shortens the feedback cycle, which is the best thing any organization can do to increase its velocity.

Small Tasks

Every task should be small - small enough to complete in less than two weeks, ideally less than two days. Small tasks are easier to write, understand, complete, prioritize, parallelize, and test. Next time you see a task that's more than two story points, consider whether it can be made smaller. Try to find at least two independent parts of the task that can be done without needing the others - or one that can be done in isolation and wait on the other dependencies. If you're finding it hard to break up a task into smaller ones, consider whether feature flags can help you make small changes against the master branch without exposing those changes to users. Smaller tasks also have the benefit of producing smaller pull requests.

Small Pull Requests

Pull requests benefit from being smaller. The complexity of a code review grows exponentially with size. The larger a pull request is, the more likely the reviewer is to miss an important detail. Larger pull requests are more likely to have merge conflicts and have multiple back and forth reviews. Even if you've been given a large task that you don't have the power to make smaller, make sure to break up the code into small pull requests - your peers will be grateful! Each PR should endeavor to do only one thing: I consider it an anti-pattern if you find you need more than a title to describe a PR.

One process I like to follow for small PRs is to first create a brand new class which is unused, except by a test for that class. Then I create a follow-up PR to integrate that class into the rest of the application. If your work on a task should involve multiple classes, you can do each of those in a separate PR with independent tests of each, then integrate them all at the end. This has multiple benefits: the PRs will be small which will allow your reviewer to focus on each one individually. You're very unlikely to hit merge conflicts because the largest PRs would never have a merge conflict - they're only adding files. The integration PR should be very small and easily reviewed. Additionally, it encourages the use of SRP and DRY since you've already abstracted the business logic into a relevant container. Finally, it makes it very easy to add a feature flag around the new behavior - just add the flag before the call site to your new class, toggling between the old behavior and the new.

Small Projects

Smaller projects are better for the same reason that smaller tasks are. They are much easier to scope, prioritize, plan resources around, and complete. In my experience, the natural tendency of any team is to make projects larger, not smaller, often through "scope creep." I've seen many projects start off as one relatively small feature idea and more ideas come up during planning. It's great to have these ideas, but it it is a mistake to include more features than you absolutely need in the first deliverable of a project.

When working on a project, look at every task and ask yourself: is this worth delaying the launch to include? If it isn't, then don't launch with it! Try to deliver just one feature at a time and put it in front of users to get feedback. This is far more likely to lead to the best features than trying to guess the best ones from the beginning.

Small Self Improvements

Hopefully you practice active self-improvement: asking peers for feedback, performing team retrospectives, and acting on opportunities. When there are many problems and many potential opportunities for improvement, how do you gain significant traction on any of them? The answer is to focus your improvements on small areas, and try to make small improvements. Resist the urge to have an action item for everything you could improve. Focus on two or three key areas that would most affect your work, and focus on making a small, measurable improvement. Once you've made that improvement, start the cycle again - in small, measurable increments.


Popular posts from this blog

Crossing the Rubycon

Building up tests via context and let in Ruby