"mmmm...code smell this has". I wish it was original but a co-worker of mine came up with it while we were making up a fictional Agile Jedi (yoda kinda). Some others were, "YAGNI this is" and "Refactor you must".
Having pulled our team, some kicking and screaming, into the Agile world. I have to wonder what has it gotten us? Also, what do we still need? Hopefully, over the next few posts, I can explore this. I know we're not perfect but I believe we're on the right track.
I'd like to start my blog by examining some of the lessons I have learned.
Lesson 1: You need a Coach!
This I can't stress enough! The agile approach depends so much on having a coach. Just like a viking war ship needs a guy beating a drum, an agile team needs a coach. The coach keeps the team on track. He Reinforces and evangelizes the agile (XP) practices. The coach is shield from scope creep (YAGNI). The coach is often the tie breaker. The coach even takes care of some of the more mundane aspects such as paperwork.
Lesson 2: Practice the Practices
After a year of forcing the issue on Test Driven Development (TDD), it hit us like a brick this really works! For us TDD became our design tool. User Stories and CRCs are what we work from. I'll cover the other practices later.
Lesson 3: Automate the crap out of everything!
We can't imagine not having an automated build and deployment system! In a later post I hope to discuss exactly how our build works but suffices to say it's cool. We can build a very complex web application, test it, update the database and deploy it to several load-balanced servers in about 11 minutes. Our CVS repository is tagged with every build and an archived package is kept. To accomplish this here are some of the tools we use: Luntbuild, NAnt, CVSNT, Psexec.
Lesson 4: Value the Values
Communication, Simplicity, Feedback, Courage. That's the subset we use. Above all we value the people over the process! With every new hire I take about 30 minutes to really explore what each value means. In later posts I intend to explore them here as well.
Lesson 5: Refactor
Get rid of redundancy! I really recommend Martin Fowler's book on refactoring! I also recommend Kerievsky's book "Refactoring to Patterns". The principle behind refactoring is to focus on getting something running THEN make it simpler cleaner, more readable. The point is that you must make time for the refactoring and it must happen often. We refactor our work everyday. Write something in the morning...refactor it in the afternoon.
Lesson 6: Keep User Stories simple
A user story should be something a User would write. Sometimes we HAVE to write the stories...it's a fact we haven't been able to get away from. IF an engineer HAS to write a story (man this really shouldn't happen) show it to someone who is not an engineer for a sanity check. Your user stories should not include words like web-service or phrases like "a class that can..." unless class is a classroom. Every story should have a user that wrote it. Every story should have a Acceptance Test as well.
Lesson 7: Use metaphors for your systems
This is an area we have been really bad...as the coach I blame myself. Your new software project shouldn't force users (and the team) to learn/invent a whole new set of jargon. The greatest (and most prolific) impediment I have seen to communication is jargon ambiguity. The project should have a common vocabulary that's easy to pick up. TRY VERY HARD TO MODEL IT AFTER SOMETHING COMMON IN THE REAL WORLD! You will save yourself a lot of confusion and lost hours.
Lesson 8: Don't over-engineer
Allow your project to evolve. Don't waste time on elaborate plans that will change anyway. Evolutionary design is the name of the game on agile teams. Have quick planning meetings every few weeks. Put the user stories away somewhere and work on/think about only one at a time. If you follow the practices (like Once and Only Once) you generally won't paint yourself into a corner and the time saved not future-proofing will make up for the few corners (very few) you find yourself in.
Lesson 9: Don't under-engineer
Yikes, am I bi-polar? Nope, just as you shouldn't over-engineer you should beware of under-engineering. Take time to spike solutions. Write tests up front and discuss all the stories with the team. Know responsibilities each story carries and how you will take care of them.
Lesson 10: Fail FAST
Fail Fast means write a failing test as soon as possible. Don't worry about the naming convention (that can be fixed when you refactor). Don't worry about inheritance or any other over-engineering concern. Just write a failing test as soon as possible. Self organizing teams are easily disorganized...fail fast will help keep a good pace. The team wants to be productive but sometimes the path is hidden. Chopping around in the bushes with a few failing tests will often reveal the hidden path.
Lesson 11: Embrace and Understand Pair Programming
On teams people will naturally pair. Let them find their own pairs. Don't continue to pair when it's being non-productive and always have a pair working on a single story. More than anything pairing (and a little coaching) refinforces courage.
Lesson 12: Be Courageous
Courage is very important. You can't be afraid to write tests first, to refactor or to ignore YAGNI. You can't be afraid to let your pair partner know when they are doing something the wrong way.
Lesson 13 (Added 01/29/08): Learn how to Write User Stories
I Actually discuss this here: Writing User Stories
I'm sure we've learned other lessons. On our team we make it rule that any story we can't fully cost is put on the back burner. It takes courage to tell a customer that you can't include a feature because the team can't agree on a solution. I say though, that in a world where so many software projects fail or go way over budget, it is better to know your risks earlier than later.