I've continually run into the same meme for the past several days, that of the absolute importance of rapid feedback to continuous improvement and sustainable success. Mark Horstman and Michael Auzenne, co-hosts of the popular "Manager Tools" podcast, recently talked about feedback immediacy. They asked several questions highlighting the importance of immediate feedback:
- What if there was a 30 second delay between your turning the steering wheel and your car responding?
- What if there was a 30 minute delay between responses during an important face-to-face conversation?
- What if there was a 30 day delay between our taking action on a project and finding out if it worked out?
They also gave an excellent example highlighting the performance of Kobe Bryant, the star player for the NBA's Los Angeles Lakers. When Kobe takes a shot, it either goes in the basket, or it doesn't. The feedback is immediate. When Kobe gets in a rut, you'll usually see him get out of it fairly quickly. Kobe has learned to make constant adjustments to the way he holds the ball, the height of his release, his aim, etc., all in response to feedback.
If I had to sum up agile development in one word, it would be FEEDBACK. Venkat Subramaniam and Andy Hunt give one of the best definitions of agile I’ve ever seen in their book, Practices of an Agile Developer:
Agile development uses feedback to make constant adjustments in a highly collaborative environment.
Here’s my graphical representation of this quote:
I have since decomposed this into an “ecosystem” of multiple feedback loops.
At the heart of the “Developer to Code” feedback loop is what I like to call "The Developer Iteration."
You see, iterations aren’t just for teams. Indeed they are also for developers. So many times I have witnessed individuals struggling to participate fully in an agile project because when they return to their desks, for all intents and purposes, they are pretending to be a waterfall. They spend days analyzing a feature, code for days without sharing any code, test the happy path toward the end of the iteration, and attempt a big bang integration on the last day. I’ll be the first to admit that I myself tried to code this way and had a couple of realizations after a short time:
- Something felt completely unnatural about it, especially in the context of what we were trying to do as a team…
- I was awfully miserable, especially at the end of the iteration.
So, what does the developer iteration look like? It is essentially a microcosm of events that occur during a regular team iteration:
- Look at your feature or task, and plan out what you have to do.
- Break the work into small chunks, where each chunk leaves the system in a stable state, yet that much closer to the feature or task being complete.
- Develop each chunk (preferably using Test-Driven Development), unit and integration testing your work along the way.
- Check-in your code EVERY TIME you again arrive at a stable state.
I’ll give my definition of stability: A system with NO broken tests. How do we maintain stability? Here are several “smaller” steps that should immediately proceed your check-in step:
- Run the tests on your development machine, fixing all broken ones until you reach 100% passing with the code you have.
- Check out the latest code from your version control system, thereby integrating your team’s changes with your own.
- Run the tests AGAIN, fixing all broken ones until you reach 100% passing with the integrated code. At this point, your system is stable locally.
- Check-in the code! Now the entire team has a stable, fully-integrated system.
So, what’s the point of all this? Look at how much feedback you’re giving yourself along the way! Each time you stop and run the tests, you’re getting feedback about the stability of your code. Not only that, but your constant striving for 100% stability greatly enhances your ability to refactor your code to keep it clean. You’re able to constantly refine the code, creating smaller methods, more cohesive classes, and an overall simpler and better design combined with the confidence that your system is functionally equivalent to what you started with prior to refactoring.
While allowing the code to give you immediate feedback on how you're doing is incredibly important, exchanging feedback within your team is equally important. I'd like to highlight three important aspects of "Developer to Developer" feedback:
- Continuous Integration (CI): CI has evolved through the years to describe the practice of having a server tool continuously monitor your team's source code repository for changes. When a change is detected, it checks out the latest copy of the code, builds the software, executes any available automated tests, and then generates a report of the results. The very best teams have this report sent to each member via email, IM, etc. You can think of CI as broadcasting the information generated by your "Developer to Code" feedback loop to your entire team. As a group you receive continuous feedback about how your combined efforts are coming together to build a working system. Any problems that require a whole-team response are immediately brought to your attention. It's also an excellent opportunity receive feedback about how your product may behave in a production setting by placing your CI system in as close of a mirror as possible of your production environment.
- Daily Meetings: While automated feedback is great, nothing can replace face-to-face conversation as the optimal means of exchanging information about software development. Meeting daily allows the team to receive feedback on how well each of you is delivering on your commitments and to come alongside those who need help. Problems that aren't detected by CI can surface in these meetings, and the team can rally around those problems to arrive at an effective solution. In either case, you're utilizing feedback to respond as a team to improve your situation.
- Code Reviews: Allowing your automated tests to give you feedback about your code is great; allowing other developers to give you feedback about your code is exceptional. The fact of the matter is, your tests aren't infallible. Look at who wrote them! As a practice, getting another pair of unbiased eyes to look at your code (test and production) has show itself to be incredibly effective at revealing defects.
Perhaps the most important feedback loop of all is team to client. You can have a well-oiled machine of a development team writing the highest quality code in the industry, but if it doesn't deliver value to your customer, it's absolutely worthless! How can we get the feedback that we need to ensure that what we deliver is what our customers want?
Think about how you drive your car. Do you hold the steering wheel absolutely stationary? No, you're constantly making tiny adjustments to the feedback your eyes are receiving about your trajectory. You move a tiny bit left, and a tiny bit right. Rinse and repeat.
It's the same way with your team. You need the ability to make constant, tiny adjustments to the overall trajectory of the software so that when you get to your destination, it's the right one. You accomplish this by having frequent demos.
The fact of the matter is, we as humans don't get better at the things we try to accomplish in a big bang. It takes kaizen - slow, incremental, constant improvement. Our understanding of our customers' requirements is not static, and neither is theirs! If you progress linearly down a trajectory leading toward fulfillment of the requirements as originally stated, you'll produce what they asked for, not what they've come to desire.
By having frequent demos of the software, you give your clients opportunities to react to where you are on the development trail. Sometimes you'll get a simple, "Great! That's what we want." Other times you'll get a correction of your misunderstandings. Quite often you'll hear, "Yeah, I know I asked for this, but after seeing it, I really want this other thing." This type of feedback is invaluable. If you don't get it frequently, you'll end up further and further off course the longer you wait.
As you can see, frequent feedback is essential at multiple levels to delivery quality software that creates value for our customers. If you're not getting it today, choose some of these practices and get started tomorrow. I guarantee that you'll get better results.