Agile "Engineering" Practices, a Cheat Sheet
Every once in a while, somebody posts an article about "The Agile Engineering Practices". Usually, it is an article about why we shouldn't do them, or why they are "considered harmful." These articles are often followed up by someone either rebutting or just commenting that the original author clearly didn't understand these "Engineering Practices" in the first place. So I thought I would create a little cheat sheet as to what I believe these practices mean. But only after a little side trip: I think we are doing everyone a disservice by calling these practices "Engineering". As we are starting to discover more about how software is a Craft, not an engineering discipline, we need to change the language. Just as a brief reminder of what we mean by Craft, take a look at the Manifesto for Software Craftsmanship. We still need discipline, but that discipline takes a different focus than traditional engineering. Not better or worse necessarily, but different. So for those purposes, let's go with Methods of Work. Now that we have discussed that, let's move on to a Cheat Sheet for the most highly recommended, yet not so highly understood, Agile Methods of Work:
- Pair Programming == Working Together – There are very few methods of work that upset people more than pair programming. “Programmers are introverts, they can’t be forced to work that way” cry the analysts. That is true, nobody can be force to work *any* way. But if we look on pair programming as just finding someone to work with for a couple of hours in the day, it's just not that bad.
- Test Driven Design == Creating your hypothesis – Rather than get wrapped around the axle of whether TDD is good or bad, lets talk about what it means. I am going to make a test to ensure that what I’m about to write works once I write it. I will still use some understanding of design and architecture to decide what the Test wants to look like, but I will express that design in terms of a test that verifies not just that I wrote the code right, but that the design is supple enough to last.
- Automated Acceptance Testing == Giving the customer what she asks for –
There are a lot of different methodologies with fancy titles for this one: Acceptance Test Driven Development, Behavior Driven Development, etc. The bottom line is that we are going to describe what we want to see the software do, then automate the verification that the software actually does it.
- Refactoring == Cleaning up after yourself – I don’t know about you, but when I am programming, I don’t always do it perfectly the first time. I make mistakes, most of which the unit tests catch. But sometimes I just don’t do the best job every time. I do my best, but that code that seemed like a good idea the first time around, when I go back and look at it again, probably could have been done better. Or maybe as my design starts to emerge, I see that I need to clean things up a bit.
- Emergent Design == Learning on the job – We need to recognize we don’t know everything about how the design needs to end up until we start creating objects and having them interact. We will start with the best ideas and design we have come up with, but we will also assume that we will learn more as we go. Another great analogy for this came from my colleague Matt Badgley: Unfolding the Map. Sometimes, we have a map with beginning and end points already understood, but we just need to unfold the map a little at a time to help us see the path to get there.
So there is my quick and easy cheat sheet. The reason for this cheat sheet is to get past the usual worries around major practices and rules as to how you must or must not do something, and get back to why we want to do it. I left metaphor off the list, as each item in the cheat sheet is just that, a metaphor. Maybe there are other analogies that will make others more comfortable with some of these practices. What else should we add to this list?