Every once in a while I hear people speaking with authority about what exactly agile software development is, and the funny thing is, they usually conflict with other statements with similar authority about agile. Often, this is coupled with negative comments about how agile is impractical because X, which is frustrating, because some of my most productive years were spent in a fully agile office environment.
So I thought that I'd write something about agile as well, if for no other reason than to hopefully point people in the direction of what I know to be a very efficient and practical means of getting stuff done. I don't want to claim that this is the One True Way of agile development though, as I'm not interested in having the kind of conversation where we re-classify everything for the sake of giving it a name. My team lead at the time, Mike Gauthier called this system agile, and that's good enough for me.
Talk Less, Code More
The goal behind agile is to have developers spend time doing what they love: rolling code, and to keep them out of meetings they want no part of to begin with. Instead developers have only 3 responsibilities over and above writing code throughout the sprint. I'll cover these in more detail below:
- A Morning stand up meeting: Every day, 10min
- Sprint meeting: 1hr
- 30min to recap the last sprint
- 30min to prepare the next one
- Any additional initiative taken to talk to the client about what they want
Note what isn't in that list:
- Requirements meetings
- Logging hours
The idea behind agile is essentially: "Here's a task, go!". The key to making this work is to keep the tasks simple and concise, so that the result of the sprint is incremental. Read: easy to deploy, with no surprises.
The rapid pace of an agile project means that the usual slow processes of planning meetings and wiki documentation becomes an exercise in futility: the job is done before it's planned, and it's changed not long after it's documented.
It sounds like a pointless process, but it's probably the most powerful part of an agile system. The morning "stand up" meeting, or "scrum" is exactly what it sounds like: the entire team stands up in a corner of the room to answer 3 questions each:
- What'd you do yesterday?
- What're you expecting to do today?
- What happened yesterday that prevented you from doing what you needed to do?
Each developer should talk for no more than a few minutes, answering these questions point blank. It's the opportunity for the team lead to address whatever problems were mentioned (after the meeting), and for other developers to find out that their colleagues are waiting for them to finish something.
Note that this meeting is not for design discussions, or gripes etc. Rather, the purpose is to be a quick update on what's going on -- which is why you're supposed to stand up through the whole thing. The minute someone starts to look like they need to sit, that's your cue that the meeting has gone on too long.
Think of sprints as a deploy schedule, but short and seemingly insignificant in what they produce. While a typical software deploy schedule may last months or even years, consisting of massive upgrade paths and a long complex list of changes, sprints are typically 1-2 weeks long. You write the code, and it's live in a few days.
The big difference from other methods is that sprints are incremental, so while new features roll out bit by bit, bugs are fixed weekly with no having to maintain multiple branches for extended intervals.
Keeping the sprint short ensures 4 things:
- The tasks are always short-term and easy to comprehend both for developers and clients
- Clients see progress on a regular, predictable schedule
- Releases are predictable, and easy to break new features into
- Your team has a concrete and easy to understand goal to work toward
But what about those elaborate project charts with tasks designated to different developers, all colour coded by week, accounting for availability?
Gone. All of it. Throw it out. You now have a binder full of post-its, or if you're feeling all 21st century about it, a Jira task list. This bundle of tasks is your code debt and should not be organised as priorities are expected to change from sprint to sprint. At most the PM should keep a loose tally of priorities, so as to make the sprint planning meetings go smoother.
Chipping Away at that Debt
At the start of every sprint, you hold a meeting in which the project manager talks to the developers about what's most pressing in terms of bug fixes and new features. Importantly, this is a two-way conversation: the PM representing the needs of the client, and the developers representing their own limitations and the quality/maintainability of the code.
This sprint planning meeting is where you take stuff out of your code debt, break it into bite-sized chunks, and assign it to the current sprint. You need to keep the tasks small and easy to achieve in < 4hours. If it takes longer than that, it needs to be broken down. This has a couple big benefits:
- Big jobs can be spread around, potentially finishing them faster
- Knowledge sharing is easier as everyone has the opportunity to work on smaller portions of a greater whole.
- It's an easy way to make big jobs suddenly feel possible.
- Finishing a task results in a sense of accomplishment for the developers
- Incremental change gives the client a sense that something is being done
No Ticket, No Work
Now that your sprint planning meeting has broken up a portion of your code debt into tasks, the team is presented with a white board with a simple grid layout:
+--------+--------------+-----------+------------+---------------+ | Todo | Developers | Working | Finished | QA Complete | +--------+--------------+-----------+------------+---------------+ | | Daniel | | | | | +--------------+-----------+------------+---------------+ | | Aileen | | | | | +--------------+-----------+------------+---------------+ | | Charlie | | | | | +--------------+-----------+------------+---------------+ | | Aisha | | | | +--------+--------------+-----------+------------+---------------+
Todo column is where you put the amorphus blob of post-it notes, each one
representing one of the aforementioned bite-sized tasks for this sprint. Note that while in
this column, they aren't actually assigned to anyone; they're simply waiting for
someone to take them and stick it onto their
Now, say that there are 30 tasks to complete before the end of the sprint.
Aileen sits down at her desk and as she has nothing to do yet, she looks at the
board and grabs the post-it about fixing a bug in email notifications. She
moves the post-it from the
Todo column into the
Working column on her row,
and opens her editor.
When the job's done, she moves it to
Finished, at which point the QA team can
now take a look, and when they're happy with the job, they move it to
Complete. If however her change broke something, or if it's simply
unsatisfactory, they move the post-it all the way back to the
where Charlie might grab it later that day, since Aileen has moved onto another
ticket about the statistics engine.
In practise, developers will often gravitate toward tasks they're familiar with, and they'll often leave tickets that have been bounced-back by QA for the initial developer and this can be ok. However if ever one developer becomes a dominant force on a particular component, (s)he might be forbidden from working on it for a while, to make sure that the other developers have a chance to spend some time learning how that software works.
The most important part of this is that developers aren't supposed to do any work unless there's a ticket for them. This keeps people on-task toward completing the sprint on-time and as expected. If there's other work that deserves attention, this is best brought up at the next sprint planning meeting.
It's about at this point where people start with comments like "What if the server goes down? Are we expected to wait until the next sprint to fix it?". Obviously not. Emergencies or "directives from on high" are things that can't wait and by their nature they can't be part of the sprint plan. They're also rare, so breaking a working system to accommodate them is a little absurd.
The solution is what's called a "spike". A task injected into the
typically flagged to be done as soon as possible. Its presence in a sprint
taints the sprint, so that it can be pointed to in the event of an overrun:
The server went down on Friday and Aisha had to burn half her day fixing it. As a result, we only finished 33 of our 36 tickets this sprint.
This is the sort of thing talked about in the post-sprint meeting, and if more action is needed (either to fully correct the problem or to avoid future cases) these tasks are added to the next sprint.
So, How'd it Go?
There's one other meeting of consequence. At the end of every sprint, you meet to talk about how the sprint fared: what went well, what didn't. In those 30 minutes, you talk about how awesome the QA team was, and how much it sucked when that module we thought would save us work turned out to create more than it solved. It's important to use this time to blow off steam and celebrate the accomplishments of the previous sprint and to take some time to figure out what could have gone better. It facilitates knowledge sharing more than anything else, and allows the PM and team lead to make better decisions in the future.
The one thing people freak out about most when I talk about this method is the lack of documentation. They conjure up nightmare scenarios where one of the developers is hit by a bus and "no one knows how their stuff works", or point out that new developers won't have anywhere to start. Both of these are non-issues though, so long as you stick to the process and don't write terrible code.
If any member of the team doesn't know how a component works enough to get in there and complete a task, then it's time to get that person working on one of those tasks. Knowledge transfer happens best through doing, which means making sure that every member of the team has her fingerprints on every part. To put it in real terms, if Daniel gets hit by a bus, the project can go on because Aileen, Charlie, and Aisha have all spent some time poking at the payment engine. Not one of them wrote the whole thing, but the understanding is there.
Of course this can only happen if the code is readable and adheres to established standards. Variable names should be in the common language of the team and be whole words, method calls should be given names that explain what they do, and class names should make sense as singular objects. If the code can't be understood by someone who's never seen it before, then it's broken by design. Making sure that everyone has an opportunity to interact with this code is the best way to ensure it's readability.
Probably the hardest part of agile software development is sticking to the process. As simple as it is, it's just too easy to fix a bug that someone found that isn't in the sprint, or add a simple feature that the client mentioned earlier that day. If agile is going to work, this can't be allowed to happen, and a lot of people have a hard time with this.
What you have to remember is that while the process feels pointlessly rigid, it's there to protect the team and ensure that the client gets exactly what was promised on the schedule that was promised. Adding in bug fixes can potentially derail the schedule, or introduce bugs that shouldn't have been there in the first place. It teaches the client that she can have whatever she wants whenever she wants, and as it's not part of the agreed sprint, she may try to get away with not paying for it.
From the developer side, it's important to remember that we like lists. If we can look at the list of stuff to do and know that that's all that's ever going to be there for the whole sprint, this introduces a sense of calm, and knowing exactly what's expected.
To this end, it's important reward a team that manages to complete its sprint ahead of schedule. If they get everything finished by Thursday, let them take Friday off. The project is exactly as far along as you expected, so why not? Similarly, if the team is routinely late in completing the sprint, overtime is justified since the entire team helped write the sprint schedule during the planning meeting.
What makes agile work is having a simple and concise plan to follow, that has been agreed upon by all parties. I've worked at companies that implement this system without involving the developers so the schedule is imposed by people who have no knowledge of what actually needs to be done. I've also worked at companies where the developers run the schedule, which is to say, there's barely any schedule at all and the results are products that "mostly work", according to whatever the developer at the time thought was appropriate. As with so many other things, the key is openness, honesty, and inclusion in the process for all sides.
Agile is a system that everyone understands and agrees to, but doesn't get in the way of actually getting stuff done. It protects all parties involved from undue stress, and unexpected results, and I can honestly say that it was (at least for me) the best system to work with.