Log in

No account? Create an account
Previous Entry Share Next Entry
What "Agile Development" means to me
Picking up from yesterday's post: thanks to everyone for your comments. It's been illuminating, and slightly sad, to see how much Bad Agile there really is out there, and how badly the "brand" has been damaged by people doing half-assed jobs of it. It was also good to hear from some folks who clearly *do* understand the concept, including a few who have fought through the always-necessary battles to put it into practice. So now I'm going to put my stakes in the ground.

Background: I've been doing Agile of one sort of another from essentially the beginning. Back in the late 90s, a few of the particularly forward-thinking guys at Looking Glass (Tom Leonard, Doug Church and the like) picked up on this hot new idea called "Extreme Programming". We played with that a little in the Siege Engine project (the barely-started next-generation game engine that we were working on when LG shut down), and then Tom put XP strongly into practice at our next company, Buzzpad, where he was the CTO. We introduced XP piece by piece, consistently finding that it made things work better, and ended up using most of it. Since then, I've been increasingly hardcore in my refusal to work in a non-Agile environment, which has led me to teaching a couple of companies how to do it, and acting as de facto project manager from time to time.

That said, my definition of "Agile" seems to be very different from what most people are experiencing. In particular, the horror story I have been hearing repeatedly (and which shows up a lot in yesterday's thread) is a misguided notion that Sprints are the heart of Agile, and that if you simply do short Sprints and daily Scrums, this will magically cause your problems to go away. This is, of course, nonsense -- it isn't the main focus of Agile, and on its own it doesn't do much to help.

So here's my concise, if intentionally vague definition of the term:
Agile development means letting go of the illusion that software development is predictable, and instead finding disciplines that work, through constant iteration and refinement.
The first part of that is the most important, and the one that many many folks are loathe to cope with. The meme of, "If we just try harder, we can predict how this will come out" is horribly pervasive in all of programming. If we just have enough sales engineers, we will know what the customers want. If we spend enough time on specs, they'll represent what the customers want. If we spend more time on upfront design, we'll get it Just Right, and can simply implement that design. If we spend enough time in meetings, we'll know how long this will all take.

It's all nonsense. History has shown, over and over and over and over again, that software is (in most cases -- yes, there are some exceptions) deeply unpredictable. And trying to force it to be predictable not only wastes time, it usually results in worse end results.

Recognizing our own powerlessness is the hardest single step here: most engineers dislike admitting it, and most managers even moreso. But once you admit that large-scale predictability is more or less hopeless (at least at the fine grain), you can instead refocus on the small scale, where we *can* achieve a measure of predictability, and build from there.

Essentially everything else about Agile is actually an implementation detail from there. That's important: those details are *not* the definition of Agile, they should exist only to support the crucial goal of breaking things down into steps that actually work. The corollary of this is that, if your process isn't actually serving that goal, then your process is probably wrong for your situation. The single most annoying thing about some management consultants is that they claim to have one-size-fits-all answers, which is an outright lie. There is no single answer for every company; moreover, the correct answers within a single company will frequent vary from group to group, and evolve over time. Retrospectives and process adjustment are annoying, but they are absolutely essential to doing Agile really well -- you can't predict the right process either, so that too has to evolve in small steps.

Sprints are *especially* an implementation detail. They're important, mind -- they tend to be necessary as a discipline for breaking things into bite-size chunks. But people who carry this to the extreme of, "Anything you can't completely finish in two weeks must never be started" drive me crazy. Yes, you have to have small, measurable milestones, but when this gets in the way of getting work done, you're doing it wrong.

So what are my typical guideposts for doing Agile? In rough priority order:
  • All stakeholders have specific responsibilities and specific restrictions. This is often the hardest step to get past, and the most important. It is difficult to convince upper management that no, you're not going to give them exact promises of what the product will look like when, and yes, they have the absolute responsibility to frequently review the state of things and reprioritize. (And often even harder to convince customers of this.) But there is no substitute for it: if the people above you are holding on to illusions, it will nearly always cause a disaster. Contrariwise, if management accepts their role with gusto, and play by the rules, it can make things ten times easier. (Implementing an agile project at Memento was enormously eased by the fact that Mike Mulholland, our Product Manager, despite having spent 25 years doing things the old-fashioned way, absolutely *adored* the Agile approach, understood it quickly, and did his part faithfully.)

  • Communication Is All. The primrose path to hell is paved with specs, which tend to interfere with honest communication. Everybody should be talking, all the time, preferably across the usual silos -- engineers, QA and product reps should all be interacting constantly. Artifacts of those conversations can be useful, but should not be used as an excuse to stop talking.

  • Frequent process retrospection. That is, the team as a whole should always be looking at what is working and what isn't. When carried to an extreme this becomes pointless navel-gazing, but taking time out each Sprint to reflect is not merely useful, it's crucial. This sort of reflection is where Agile came from in the first place, and since every project's needs are different, every project needs to set aside time to do it honestly.

  • Fast and frequent iteration with customers. This isn't *quite* the entire point, but it's not far off. One of the most important illusions to give up is that you actually know what you should be building. (Which requires the customer giving up the illusion that they really know what they want.) So instead, you get something in front of real users (or the nearest thing to them as you can get) as fast as possible, take their feedback, and keep iterating quickly. The ideal is "every sprint is a release", meaning that the results of each sprint get shown to the customer representative, which is doable iff they are sufficiently tied into the process.

  • Flexible scope. This one's often not mentioned explicitly, because management doesn't want to hear it, but in practice it is always essential. The central illusion that you must dispense with here is that you can predict what will get done when. Since that isn't true, this means that either the schedule or the scope *must* be flexible. 90% of the time, the correct answer is scope -- you know when you will deliver (since that is often driven by externalities), but can't promise precisely what.

  • Story-centric development. You don't try to write deeply detailed specs in advance; rather, you design *enough* to know approximately which way you're going, and otherwise prioritize in terms of medium-grained Stories. These should ideally be smallish -- on the order of a few days' work each -- in order to make them more tightly understandable when the time comes, and should be as independent as possible, so that you can reprioritize flexibly.

  • Frequent but predictable reprioritizations. Specifically, the rule of thumb I like is that the Product Manager / Customer Representative is allowed (and encouraged) to revisit the priority order of the Stories between Sprints, but not during them. This means that the engineers can focus on getting work done most of the time, but everyone has an agreement that priorities can and will change pretty often. The highest-priority items should always be at or near the top, so that they get shipped. (See "flexible scope".)

  • Deep testing and constant refactoring. These go hand in hand -- the XP phrase that I've always loved is "Coding with Courage". If you try to code too conservatively, you wind up with unmaintainable spaghetti. You always have to have the courage to make the code *right*, and the only way to get that courage sanely is to have enough QA -- preferably mostly automated, but there usually needs to be a mix. (I am often bad about putting enough tests into place, but I recognize that that's a flaw.) Nowadays, I usually recommend making it explicit that engineers are responsible for much of the testing; simply dumping it on QA people isn't acceptable.

  • Code Sharing. One of the relatively important and often overlooked tenets of XP is No Silos -- all code is shared by the team to the greatest extent possible. In practice, everybody hates this: managers dislike it because they don't have a simple answer to who to ask which questions, and engineers dislike it because it breaks their deeply-held "My Precious" attitude towards their pet code. But it is essential if you are going to be serious about following the priorities: if people are silo'ed, those silos usually won't match the current need. This requirement in turn drives the need for deep code review and/or pair programming.

  • Short Sprints. Yes, I've deliberately listed these last, because I honestly think they are the most implementation-detail aspect of the whole thing, and not always even necessary. Sprints are typically required as an artifact of scale. You need them to provide a regular clock for the management / engineering contracts, to keep everyone from annoying each other. You need them to remind you to reprioritize regularly. You need them to remind you to keep your stories small. But the truth is, in a *very* small team with *very* tight communication, they can simply get in the way. (Querki used sprints out of habit for the first year, but about six months ago I simply dropped them -- they were simply overhead at the moment, and not adding anything.)
Finally, yes -- Agile Is Hard. Don't let anybody tell you otherwise: if they say the process is easy, you're heading into badness. Setting up Agile processes at any company usually requires 6-12 months of hellish argument, as you figure out the processes and responsibilities that work within your environment. Even once it *is* working right, everyone has broad responsibilities for constant communication and small-scale planning, and need to always be disciplined about it. Many engineers resent that, but it's part of doing the job well.

  • 1
Good stuff; thanks a lot!

Regarding silos, I remember I was intentionally rotating the code and the responsibilities in the team, so nobody owns the code (the company does). And it was really good, especially taking into account that there were many young women that had to leave for about a year and then get back, and this should not have destroyed the whole thing. It worked.

Yaas. One of the practices I'm increasingly fond of is mandatory code reviews. Folks get a lot less resistant to this once it becomes clear that this isn't about me looking over their shoulder -- this is at least as much *me* wanting *them* to look at my code, so they understand how it works and can work in it themselves. Once it stops looking like a power game, I find that many people warm to the idea, and it helps support the "anybody should be able to work in any code" concept...

I as a proponent of code reviews; now I'm totally against them. First, one has to explain half-baked ideas all the time as if they were something worth keeping. Second, people become conservative, and that's bad.

I remember at Google newly-trained js programmers were telling me never to pass around functions; "you are supposed to use bind" - my question "what for" was answered with something like "because we do it this way". Etc.


Code reviews are great. For a few reasons:

1. It means that at least two people have looked at the code.
2. It means there's an opportunity to learn -- in either direction.
3. It shares responsibility (in a very real way).
4. In practice, it helps a lot of garbage -not- go into the codebase, and catches bugs that would be hard to test for.

But...you have to do them right (authority goes both ways; anyone can learn; it's a dialogue) and it's only as good as the people doing it. If nobody knows what they're doing, nobody's going to learn much.

OTOH, in the example you listed above...you were handed an opportunity to teach stuff. Where's the bad?

Right, teach them... It was in Google; and not being someone with power and connections, I was not in a position to teach anything. It was Google.

More, not sure about your experience, but I noticed that the chance of meeting an asshole in our profession is pretty high; and instead of learning something or teaching something, you get involved in a fight regarding who's smart here.

It was in Google; and not being someone with power and connections, I was not in a position to teach anything. It was Google.

Reason number... well, #1 of why I prefer to work for small companies. When the individual contributors feel that they can't influence policy, I begin to get cranky. (I do sometimes wonder, if Querki were to become successful, how I could promulgate a culture that I would actually enjoy working in.)

I actually interviewed at Google, twice. The first time went extremely well, but I had to cut the process off because my wife had become ill. The second time went *horribly*, mostly because I went in with a bit of a chip on my shoulder. But I suspect that I wouldn't have been a great fit, for this reason -- for all that Google made a big deal at the time about behaving like a thousand startups lashed together, that doesn't seem to match the realities I've observed. It's just plain hard to empower everyone when you have tens of thousands of employees.

More, not sure about your experience, but I noticed that the chance of meeting an asshole in our profession is pretty high; and instead of learning something or teaching something, you get involved in a fight regarding who's smart here.

I will admit that I have the advantage of having worked my way high enough up the ladder that this is less often a problem. I get into arguments, but it's rare for somebody to be able to pull seniority on me, and it gives me opportunities to set a good example of how to deal with them. (Or at least, what I like to think is a good example; I will admit to sometimes failing my own standards, but I do try...)

Experience: ~17 years of dev, 11 of it at Experian. (none of it at Google).

Assholes happen, but it's still not the norm. Even when you get into a discussion of who's right, it's possible to be civil, and let things come down to agree-to-disagree, style guide, group consensus, or whatever. If the person actually -is- an asshole, they'll be hell to work with regardless and it's nice to have it in the open, so you can work things out. (even if "work things out" means talking to HR/management or leaving).

The solution to "some people don't work well with others" isn't "depricate use tools that allow collaboration"--it's "don't work with those people."

I think there is no problem if someone wants to do something in "his way" as long as there are no agreements on coding style and coding practices in the project you are working on. So in general I would say that "because we do it this way" answer could be accepted as valid unless the reviewer can propose a change significantly simplifying code being reviewed.

I'm a big fan of code review practice and can't imagine my life without it. It's definitely about learning, but at the same time about looking for missing use cases, wrong logic, test coverage etc. Show me that what you've implemented is actually working! This is also a part of code review.

It's the reviewer that knows just one way to do things, and thinks that the world should never change because of that.

I am also a big opponent of uniform coding style. I was a proponent not so long ago.

I'm on the fence in terms of coding style standards. It has its advantages in terms of being able to share the code around the team, but just gets in the way when carried too far. My guess is that, if the guidelines get longer than a couple of pages, you're probably over-thinking it. My suspicion is that it's best handled in terms of FAQs -- if something *frequently* causes problems it may be worth standardizing, but otherwise isn't worth the hassle.

The one I am currently wrestling with in Scala is whether Option values should reflect that in their names, though some variant of Hungarian notation or an "Opt" suffix. On the one hand, it is strictly unnecessary if you're working with a modern IDE, and Scala kind of demands a good IDE. OTOH, I find that code is just plain more comprehensible when I can tell at a glance which vals are Option and which ones are simply identity -- it saves me a lot of small map vs. flatMap errors and the like...

:) Currently working with a Hungarian, I see a lot of Hungarian notation in his code I inherited; it looked weird first, but then I picked it and started doing it from time to time myself, when two values have essentially the same content, but one is string, another is option and the third is "pure value". And I think it is good not to codify, but just share experience. So we would not have methods like 'isDoesNotHaveUnsupportedOperations(data)'.

Yaas. Having spent 5-10 years working in Windows COM (where Hungarian notation is a deeply-baked de facto standard, and necessary for survival and sanity), the idea comes fairly naturally to me. But I've gotten away from it over the past decade, so I'm not taking casually the notion of introducing it into the Querki codebase...

Agreed with the "on the fence". It's pretty useful in terms of avoiding the pointless arguments -- decide whether you're using tabs or spaces, how much indent, all that nonsense so the code isn't a mess and it's easy to see what was changed. And it can be useful to resolve a pointless argument one way or another so it doesn't get argued over and over again in review.

But you don't want to lock out entire parts of the language just because someone doesn't like/understand it, nor lock out new ways of working.

Yaas. And with Scala, that's going to be an interesting line to walk, since the language can get *so* ornate (and confusing) if you let it. I suspect that I'm going to gradually evolve a sense of what-belongs-where (including some guidelines for proper usage of implicits, which are Scala's greatest double-edged sword), but hard and fast rules are mostly inappropriate...

I think it heavily comes down to *why* you're doing code reviews. Traditionally, they have been considered to be 100% about code quality, and I agree that that's a bad idea -- that's what automated testing is for, and I concur that it makes people conservative.

But I've found a lot of success promulgating code reviews as a way of teaching people the code. Yes, it does sometimes require explaining something that's half-assed, but that helps keep me honest: admitting to someone that it's half-assed reminds me that it's going to need to be revisited. And the defensiveness gets a lot easier when the process begins with the Architect pulling the Intern in to review his code -- that helps drive home that, yes, we all do this, and it's mainly about spreading knowledge instead of looking for things to criticize...

But the truth is, in a *very* small team with *very* tight communication, they can simply get in the way.

Doing without them has a name - Kanban, which sits pretty solidly in the constellation of Agile variants, and has it's own recommended processes.

Yeah, I was sort of suspecting that what I am currently doing was approximately Kanban, but I hadn't dug into that enough to know whether it actually was -- I really only know Kanban at the hand-wave level at this point. (Mostly in the context of swarming to deal with blockers, which seems to be the one idea from Kanban that everyone talks about.)

Useful to know, though: when I have a spare moment, I should probably read into it more and mine it for ideas. Thanks...

  • 1