A good amount of the processes and tools we use in development aim to reduce the feedback cycle between a task and the observation of its results. This occurs at every level, from the company to single code lines. While the industry has been working hard to reduce those cycles’ duration, ultra-short cycles – while tactically attractive – can handicap a project on a strategic level. Finally, code reviews are a special case, as you need to take into account both the reviewee and reviewer cycles.
This post was inspired by a discussion with Stéphan about the ability to “push F5” to observe in the browser the change I just made in our Rails application. It made me think back about the importance of good feedback loops, at almost all levels, but especially in development.
Feedbacks at different levels, with different timings
A development process is a series of feedback loops, each embedded into the previous (longer) one.
At the company level, I blogged some months before about my unit tests taking 9 months to run. Jokes aside, this is exactly the issue: how to get feedback about how you are doing/progressing – in this case about your business.
At the development team level, setting up a feedback loop is what the sprints in Scrum/Agile methodologies are all about: get your customer (representative) at regular intervals to showcase the progress made. This meeting is not just about providing the customer with relevant information about the project (a working demo, not a “we are 80% done” – I’ve seen too many projects that were “80% done” and where the 20% used as much time as getting there).
Its other critical function is to provide the team with the feedback they need: Are we really developing what the customer wants? Does it work at his or her level of expectation (regarding to UI, performance or any other point)? The importance here is to get feedback from the relevant party - if as a developer I think the performance is crappy, but it is “good enough” for the customer, it should not get high on the priority list, even if it probably deserves a mention “We could make this run much faster with some work”.
Daily Scrums are the next implementation, but on a shorter, tighter level: the focus is on a single day (between yesterday and today), and on a single development team. Again, it is about getting feedback on both your own activity (“I will be doing X today” allows people to question it if needed) and on your teammates’ activities.
When speaking about development itself, the whole continuous integration process is exactly about that: getting feedback on the state of the software as soon as possible – by setting up a working version of the software with each commit (VCS) or push (DVCS).
Even before your push, you’ll want feedback about your modification. This can typically be done by writing (and running) Unit Tests. While the benefits of unit testing are manifold, a key benefit is getting crucial feedback about the code you wrote: does this new function works? Is this bug really fixed?
Getting back to my first sentence, most development frameworks or processes have pushed a maximum toward reducing the code/test cycle, allowing – for example – to observe the results of a modification directly in the browser, just by hitting the F5 key (if you are lucky enough to not be working on processes taking hours to finish). This has become so easy (for example in Rails, but also in most modern java web development) that I would have trouble getting back to something longer (like redeploying – or worse – not being able to run the software on the machine I’m working on, which are situations I did encounter in my career).
Code reviews are of course also a great feedback opportunity, and as each good one, it is useful to the project both through the reviewee and through the reviewer – both have an opportunity to learn something.
Good cycles versus bad cycles
Lots has been done in our industry toward adding feedback loops where they were missing, and toward reducing cycles time. This is (logically) well documented, with the benefits of “failing fast”. I won’t get back to this debate. Instead, I’ll take a look at the pitfalls of short cycles. While shorter loops are without questions a good thing – especially seeing where we came from - there is a real danger of having loops that are “too short” at almost every stage.
Some examples :
Sure, I want my customer to give his feedback about the software. But I do not need my customer opinion about each build, some of them may contain experiment, non definitive (or non working) UI. This is the reason why sprints emphasize feedback, but also organize them in a way that does not interfere with the delivery of working software. Daily scrums are not that much a solution to collect basic information about the team tasks than a good way to have it in a quick and efficient manner, thus diminishing the “What are you doing now ?” kind of interruptions.
I would not want the CI to run each time that I save my code. I knowingly save code that is not optimal, or even non working (it is the reason I run through other loops such as unit tests before triggering the CI).
While I did play with some software to do this, I do not want my unit tests to run at each keystroke. When you make changes to code, you break things, the idea it that this “break” will never be visible from the outside – I’ll have it fixed and the test running before I even commit.
Even if I like the short code/test cycle, it can lead to inefficient behavior, such as relying on pure “trial/error” strategies. While “trial/error” becomes comparatively cheaper in short cycles, this strategy risks replacing high-yielding / costly activities such as – such as design thinking.
Finally, if I value the review of my colleague on my code, it would probably be awkward to have one of them comment it as I type. Part of my thought process (YMMV) implies writing and rewriting (whether it is for a blog post or for code), meaning: I do write sentences or code lines just to make my reflexion evolve. I know those will be gone and replaced very soon (between a couple of hours and a couple of minutes). Having someone review what is basically my thought process would be awkward and totally inefficient. I must confess lacking much experience in pair programming, but I would suspect that practitioners would not ask “why” at every keystroke. Even in a situation like pair programming, you want to let the developer with the keyboard the time to do a relevant part before giving him feedback (“relevant” may be a couple of minutes and ten line of code).
Code review cycles
Last but clearly not least, finding the “good” time for a code review is no trivial task either. This is a subject of peculiar interest to us at 8th color, both as a development team and regarding our work on a Ruby automated code review software.
We have been talking to a lot of Ruby developers lately, and code review is – for each of them -something important, it delivers terrific value, but is a real pain to set up properly. What we agree upon is that the best timing (for the reviewee) is probably at the end of a well defined feature: small enough to be reworkable, big enough to have some sort of finished piece to discuss (and not an half baked idea). Having it done at a specific point (in the code evolution) makes it much easier for both the reviewer and reviewee to extract a maximum value of it.
Of course, that does not deal with the problem of the good timing for the reviewer. The additional difficulty of the code review cycle is that is implies two similar functional profiles – developer but in very different roles. The chances that you’ll finish your feature and ask for my review at the exact time I’m finishing mine are thin, and the typical solutions appropriate for other cycles (such as the sprint) and not good fits here, as waiting would diminish the value of the review very quickly. This is one of the keys problems we want to help solving with our new product.
On a general point of view, my personal take is that feedback loops are good, but that the important point is having them at the right time – for the right time – without an exclusive focus on shortening cycles. You do not want to take action at each instant feedback – it is impossible, and it would be a bad idea anyway.
Finally it’s interesting to see how the many very different tools and processes we discovered in our industry those last twenty years are different takes on the same problem: how to collect proper feedback on our work?
From Unit tests to Sprints, from Code reviews to Lean Startup, everything is about getting feedback.