If I have any bias concerning this topic it is that I'm a long-time strong believer in eXtreme Programming. Heck, I was agile when agile wasn't cool. In fact, it wasn't even called agile yet back then. We founded XP Atlanta before the manifesto meeting in Snowbird. And back in 2000 my team gave me a red cape with a big XP on the back. It wasn't until later that I realized that they thought of me more as a super-villain than a super-hero. They wanted me to wear the cape so they could see me coming. And hear me when I made the swooshing noises. But I digress.
I'm otherwise fairly balanced with half my career using a plan driven approach and the later half using an agile approach; and most of my career as a programmer but more than several years in management and product management.
ENGINEERING PRACTICES IN XP
So, first, before we look at Scrum, let's look at the engineering practices in XP. This is the briefest of summaries of these practices.
As an aside, the non-programmers on our teams need to understand and appreciate what this stuff is. Be kind and explain it to them in a way they can understand. Offer them a non-technical, or at least very lightly technical, lunch and learn. This will help us all work together in harmony.
Pair Programming is far more than continuous code review. The pair is thinking on multiple levels: one about the low-level details, names, indentation and syntax while the other is thinking about the big picture, whether this test is sufficient, whether it's the right test, what's the next step, about the next refactoring, and may be helping look up something in the language or API docs. Pairing improves quality and speed of development, or it at least increases the longevity of the codebase by holding entropy at bay. Pairing supports simple design and helps enforce the use of these other practices (peer pressure).
If you are just watching the other guy code, you aren't pairing. Pairing is active. Who has the keyboard should change every minute or three. Try using the ping-pong technique whereby one programmer codes a failing test. The other programmer then makes that test pass and codes the next failing test. Then the first programmer takes over again, and so forth.
Test-Driven Development is where a test (that fails) is coded before the production code (that makes the test pass) is written. TDD supports Refactoring and Collective Code Ownership and Continuous Integration and other things like small releases and iterative development. Out of doing TDD you get automated unit tests for all code. (Or automated acceptance tests for all stories for ATDD.) A related technique is to write an automated test to reveal a defect before the defect is addressed.
Continuous Integration is where you integrate changes daily and preferably much more often. The opposite, of course, is leaving integration until later, which is often a tedious, lengthy, buggy and painful process. A student of lean will learn that leaving integration for later will lessen the likelihood of good luck. Or, delay causes waste.
Refactoring is improving the design without changing the functionality. Many don't do this right or well. It's best done "in the small" all the time, not in large steps and infrequent. The later may be design change, but I'm loathe to call it refactoring. Good examples are small things like rename class, extract method, move method, introduce variable, etc. Most of these common refactorings are supported by the IDEs we use today, such as Eclipse, Intellij, and VisualStudio with Resharper. Proper Refactoring supports simple design and testing.
Coding Standards supports Pairing and Collective Code Ownership. I don't recommend writing your own. There are many published coding standards. I suggest adopting one of those.
Collective Code Ownership is where everyone on the team is responsible for that team's code. All team members may change all the code. We're assuming we have a small team (or teams) of 7 +/- 3 coders. This practice reduces delay (waiting/blocks) and risk. For this, you need pairing and tests.
Simple design -- It's simple design, not simplistic design. Simple design makes code understandable and therefore more maintainable and modifiable.
System Metaphor is a story that everyone can tell about how the system works. This usually yields a system of names. It supports Collective Code Ownership and Simple Design.
So, that's just the XP engineering practices, not all of XP's practices. And that's about XP. That's not about Scrum.
BACK TO SCRUM
But the topic proposed for Atlanta Scrum group was "Exploring the Engineering Practices Necessary to Support Scrum".
So let's get around to that, but before we do, let me take one more detour. If I wanted to find a definition of agile on the internet, where might I look? I'd look on Wikipedia: http://en.wikipedia.org/wiki/Agile_development
Lo and behold, a definition of agile. And, there's a picture of Sutherland. I'm a little miffed that Scrum gets top billing, but at least if I page down, I see a picture of a couple pair-programmers practicing XP.
Now, what are agile engineering practices? I've shown you the XP ones above. What are the 'Scrum' or 'agile' engineering practices? Can't I find that on wikipedia too? Not as of today, but it was suggested to me during my talk that I should fix that.
My point here is that there is no commonly accepted definition of what the agile engineering practices should be, at least not well enough to make it to wikipedia. I say all that to point out that the stuff written below is more of my opinion than are the facts about XP I've stated above.
ENGINEERING PRACTICES NECESSARY FOR SCRUM
What are the engineering practices necessary to support scrum? Go ahead. Write them down. I'll wait.
That's a nice list you have there, but does Scrum make them necessary? Are they necessary because you are doing Scrum? Is it specific to Scrum or is it agile in general? Here's my list of engineering practices necessary to support Scrum:
I categorically say no to all the practices on your list. None. There are no engineering practices necessary to support Scrum.
The question is a non-starter for me. And I say that as an XP fan, a process that believes in the importance of a specific set of engineering practices. I take exception on two grounds. The first is the word necessary.
Necessary is a bit of a strong word. It's kind of like saying always or never. You never take out the trash. You always make me walk the dog. You never put your dirty clothes in the hamper. You always leave the car on empty. You never say you love me any more. Things like that.
The second is the assumption that if you are doing Scrum you must also be involved in software development somehow. You might not be engineering anything at all.
Lots have blogged on this and there was a good debate on twitter about it (involving Jeffries or Shalloway or Sutherland or Schwaber?). It was about Scrum being sufficient or whether it needs development practices. One side said Scrum by itself is insufficient. The other said Scrum is what it is, it's fine as defined, please do use engineering practices, but Scrum doesn't need to be changed.
My wife runs our household using scrum. She's not the housewife, homemaker, domestic engineer: She's the product owner. (My 13 year old daughter who is made to clean the bathrooms is the scum master. But that's another story.) The point is, there are no engineering practices needed for Scrum to be useful in a household.
A team I once coached was the payroll department. They weren't engineering anything. They were building nothing. But they had initiatives and duties that they managed using Scrum. No engineering practices needed.
Pillar's recruiting team uses an agile approach. Pillar's on-boarding process uses an agile approach. Pillar's management uses an agile approach to manage our internal process improvement initiatives. These don't need engineering practices.
However, I know what you mean. I understand the real question. Maybe this is the question to ask:
When you are doing software development and Scrum, are there engineering practices that help?
Now you can bring out your list again.
But does Scrum make them necessary? Or are they universally necessary when doing software development in the current set of popular high level programming languages, namely Java and C# and Ruby? For the most part, I'd say universally helpful. So, we should scratch Scrum from that question and state it thusly:
Are there engineering practices that help if you happen to be on a project involving computer programming?
Given that, here's my ordered list of useful software engineering practices. I am representing these as tiers upon which the more basic and most important are the foundation upon which the others are built.
Starting at the bottom, we have Continuous Integration and Automated Unit Testing. You get a lot out of this. It can hook most people, being a gateway drug, I mean, can help most people and it's a great place to start. Everything else is harder without this
I didn't list source code control, because, everyone does that now, right? I guess there are some things I just assume, and that's one of them.
I could put pairing in the bottom and that would make the other things more likely, but the rest could happen without pairing, so that is later. Besides, the business reality is that it's hard to find enough pair-programmers, so I'm resigned to think that I'll often have a non-pairing team somewhere in my organization.
Similarly, TDD makes sure UTs, refactoring, and emergent-design happen and has other advantages. But you canunit test without TDD, so TDD is higher up in my list.
How about sustainable pace? Is that a technical practice? I'm thinking it's more of a (project) management practice than a strictly technical practice. Otherwise, I'd stick it here.
You need tests before refactoring. Some would argue that you need refactoring to do automated testing. Lots of truth to that, but strictly speaking, you could test without refactoring. But you need TDD and Refactoring to support Tier Three.
In this tier is Simple Design. Simple is hard. To make things simple, you have to be quite knowledgeable about numerous design concepts. And you also need to be just plain good. You have to be knowledgeable in areas that can make your designs anything but simple if misused, which is why I said you also have to be 'just plain good' in addition to knowledgeable.
Also in this tier is Knowledge of Design Patterns. I didn't say use of design patterns. Use them in your conversations as shorthand, for a concise, rich with meaning way of communicating. But use them in your code carefully.
You should know SOLID design principles if your system is object oriented.
Emergent Design and Emergent Architecture is about recognizing the fact that we aren't going to get it right the first time. Let the design emerge/evolve over time as we learn. Even very very smart folks, the top folks in this field say they don't get it right the 1st time. (Seems like I should try to give a reference to that. Eh, I'll just put an unsubstantiated claim that I bet Cunningham, Jeffries, Uncle Bob, Joshua Kerievsky, Kent Beck, Corey Hanes, and may others would agree.)
This tier is really all supported with 'Ongoing Education', continuous learning. I really think there's lots to learn there and the field continues to grow. This is so difficult to do really really well, that we can never stop learning.
Collective Code Ownership and Pair Programming require a Coding Standard.
As I mentioned earlier, Pair Programming is really a foundational technique, but I can't say that it's for everyone. I'm a strong believer in the technique and have required most of my employees give it a try for at least a month, though it can take two or three to really get accustomed to the approach.
This is the just good old good to know tier. In here are some things that may change or be replaced by something else over time, more so than the ones in the other layers. This tier also includes things to have in your tool box, though you may never pull them out to use them:
- Code Coverage
- Cyclomatic Complexity
- Other Code Metrics
- Domain Driven Design
Some might argue with me for putting ATDD or maybe BDD so high up. There are numerous techniques for automated testing at a higher level than unit testing that teams can choose from. I didn't want to list them all and I didn't want to say that one was better than others in all cases.
Likewise, Domain Driven Design is a useful technique, but I can't say every team must use that technique over another.
BACK TO SCRUM
Is there anything in Scrum that should lead us to do these things? You need these things to be agile software development team and these things support time boxed iterations. But there is also the Definition of Done. Some Scrum teams define what done means and hopefully it includes explicitly or implicitly some of these things.
After my talk at Atlanta Scrum on this topic last week I gave a demonstration/explanation of TDD. Surprisingly, I got more positive feedback about that than I did the presentation. Not that either was stellar, but I was expecting a different crowd than what showed up.
Contact me for a TDD demonstration or agile lunch-n-learn at your office.