Wednesday, June 4, 2008

Agile Development

I'm an agile developer, but I don't use XP or Scrum. "Agile" is the umbrella term that includes XP, Scrum, and a host of other practices. "Agile Development" isn't a methodology unto itself.

To me, the heart of Agile is adapting to change; being flexible; being able to change quickly. Citing "continuous attention to technical excellence and good design" as a principle sounds disingenuous to me. That's not what separates Agile methods from other approaches. Likewise, citing Simplicity isn't very useful unless you make it clear what you think Complexity is. Yeah, messy code is bad. I'm not sure who you're going to find that's going to disagree with that.

The key observation that leads developers to agile methods is that, as programmers, we learn much more about a problem and its solution by solving it than by staring at it. Agile is the opposite of Big Design Up Front. Planning is a good exercise, and I think any competent dev team has a plan -- but when they learn more about what they're building, they'll be more willing to change that plan (and come up with better changes to boot). The core argument here is that solving a problem produces information about a problem faster and more effectively than planning alone.

There are three major practices central to agile methods. They are iterative development, top-down development, and flexible code.

Iterative development means making frequent releases. If you want to adapt to change, then you need to adapt; to change. Grossly, there are two approaches here: (1) build the whole thing, then stand back and see what you need to do different, or (2) build some of it, then stand back and assess what your next step is. Iterative development breaks up a big project into small chunks so that you can get something finished -- to make progress -- before you go gallivanting off in another direction.

An agile developer can shuffle priorities around at each iteration. Quick iterations also means more visibility up the management chain; they know where you are because you released something recently that shows where you are. Iterations also give your customers a chance to give feedback before you've gone "too far," and it provides a chance to reign in a wayward developer who has gone too long without contributing to an iteration.

I think most of the benefit of frequent iterations is incorporating feedback. To me, a big up-front design that calls for frequent releases seems squirrelly. Why are you releasing if you're not going to listen to feedback? If you're using a waterfall model, then your interim releases are going to be full of bugs, untested, and probably won't have a cohesive set of useful features.

I like planning using something small and physical; I haven't been too happy with any of the automated tools I've seen. I write down features on index cards, and sort them by priority. Every time someone completes a task, they go to the table-o-index-cards to grab their next task. (Usually they know ahead of time which set of cards are going to be theirs.) When too many features show up and/or developing an important feature takes too long, it is real fucking easy to see what tasks fall off at the back end.

Top-down development is making something simple that runs and slowly adding new features to it. I think one of the great bugaboos in software development is YAGNI, and top-down development is its cure.

In games, it's fun to get something working quickly. Plus, something working quickly gives your team more time to figure out what works and what doesn't, to see models and animations in action, and to start playtesting and thinking about balance.

Adding new features can be difficult if your code is a mess. Working around that is my third pillar today:

Flexible Code. It's hard for me to explain what this is, because unflexible code just looks so alien to me that it makes my brain hurt. The bad practices that hurt the worst here are hidden side-effects, large functions, blob classes, opaque data structures, and automation.

Automation makes a lot of things easier, but it's horribly inflexible. By "automation" I mean code structures that encapsulate some set of features into a magic little opaque blob. (You're not detecting any bias here, are you?) "Automated" code magically sticks items into queues, deletes items, changes variables, etc etc, usually in ways that someone debugging code would never know about. "Automation" often makes systems significantly easier to build, once you've learned your way around the code. But bugs can be a nightmare to remove, and god forbid someone new has to learn the system. Or its original developer leaves.

Ultimately, the goal of agile methods is to increase productivity. The two main ways this happen is by only writing code that you actually need -- by prioritizing up front and coding top-down -- and by making it easy to add new features. Some of the most frustrating experiences I've had while coding have been when I've been faced with a system that violates some of these rules. 3rd-party systems are often the worst, because (for contractual reasons) you can't see their source code, so the whole thing becomes magic. How does it work? Who knows! Plus they never bothered to document anything! Grrr.

There's tons of resources out there on agile development, but my favorite is the c2 wiki, aka WardsWiki, the firstest Wiki evar. I learn a lot more from reading both sides of an issue and making up my own mind. The C2 wiki is a great place for that. :)

No comments: