I've been using XP concepts since Kent Beck first published his book Extreme Programming in 1999. A couple of contracts between 2002 and 2004 used snippets of Agile. Those that I groked (meaning: understand profoundly through intuition or empathy) I took with me to a new contract starting in 2005.
Agile is not prescriptive. It is not: thou shalt do this; then this; then this...
I'm contracting at a company where Agile has not yet been adopted, but being seriously considered as I write this.
When I started, Agile was an unknown concept to the company. I had to have the "XP Courage" to pick the Agile techniques I considered useful, and get on with it; without telling anyone.
Forcing a new methodology would have been impossible. I was hired to working on specific applications - not as an architect for their development department!
So what Agile techniques did I use?
"What did you do yesterday; what are you planning to do today; what problems are you having? "
Really an adaptation of stand-up meetings. (We sat down.) The meeting was held first thing every morning.
Problems raised were discussed there and then. As there were usually only 2 of us in the meeting these discussions didn't waste anybody else's time.
The meetings were short - usually over in 5 minutes.
They're a good way reduce interruptions during the rest of the day. I take a long time to context switch: any interruption is not recommended. (After a few glares the permie begins to learn!)
This is somewhat stilted, but is an easy to follow rule. Don't check in code, unless you have an engineer with you, and you can convince him and yourself that you are about to check in quality code.
Sometimes the act of describing your code makes you re-think, and abort the check-in.
At one contract the method of summoning an engineer was to strike a tubular steel frame with the palm of your hand. Whumph-ting! An engineer, who's available or interruptible, would wander over to my pc and the review would commence.
Peer Programming has 2 flavours.
Cynically they are:
Pair programming - the technique where two of you fight over the keyboard.
Side by side programming - where you have two separate pc's a couple of feet apart and you sit close to a chum and chat.
We pair programmed as required. Certainly not more than half an hour or so if we chose to share the same machine. Keep it fun. Stop before any blood gets spilt. You and your partner will get frustrated... keeps making silly mistakes.
One may write unit tests: the other writes the class to test. This close interactive work can lasts days. And it's fun!
Works well if one is "doing" the server and the other a client. Or one is "doing" a host application, and the other a library dll. (Sorry, did I type dll? I meant assembly.)
Not really Agile. The reality is you do have to look over someone else's code.
Design and code the unit tests for each class, just before you create the classes. Have a test suite that will run the unit tests quickly.
Capture any reported bug in a regression test. The regression test should initially fail - so you know you can reproduce the bug. Fix the bug. The regression test will now pass. Always run the regressions test before the next release. You can then guarantee you won't be giving you customer the same buggy code!
Regression tests will probably run a lot slower than unit tests. For example a database may be dropped the rebuilt many times as a regression test is run. A unit test should test your code. You may choose to use a different namespace to "stub" out a slow SQL library during unit tests. The "full monty" should be used for Regression tests.
Always build you code last thing at night. Run the code on a staging machine. Feed it with live data. Feed it with data you've previously captured. Will it survive the night?
Use a "clean" machine to build. Use a virtual pc to "blow it away"
Continuously test the latest modules on live data.
This involves a printed piece of paper that gets ticks and eventually will get filed.
Check the release number; have the unit tests and regression tests run? Sign off from the business.
Build confidence and get the warm fuzzies by focusing on end to end testing.
You must have something to test. Have a path that follows the data flow. In that path build modules. Some modules will do nothing initially, but will allow an end to end test. This is then run nightly.
Litter the source with assertions. Assertions tell the next programmer what you expect to be happening.
One bright spark I had the misfortune to know has a good way of getting rid of assertion errors - just remove the assertions from the source code and add a "try catch" block that swallows up any memory over-writes. Having this fellow's code module running with my code was like having a shot gun going off, randomly peppering my structures with memory over-writes.
Beware feature creep.
Identify features to go into the current preview. (OK we called them releases - but the internal customer new they were functionally incomplete.)
Identify features to go into the next preview.
Identify features that would that would get entered into the backlog.
If in doubt about a feature ask "Will it sell more product?". Also prioritorise with the customer.
We prioritorized backlog issues with the customer. We categorized features as:
1, Important, for the next release.
2, For a later release.
3, Unlikely to see light of day.
Backlog meetings were fun. and a bit frustrating for the customer. Timescales are difficult to predict accurately. Sometimes a lower priority feature would get implemented - if an engineer in working in that area, and is immersed in that part of the code - why not slip it in? (This is still disciplined: it's a feature that the customer wants; not some feature that an engineer thinks the customer wants.)
Define your interfaces as soon as possible. Stub them out. Other teams and or other team members can write to these interfaces.
problematic if you check in code where the interfaces have not been completed or poorly named - very disruptive to your co-developers.
Hide any internal code changes from other developers. (Sounds bad!) What I mean is that as you iterate though your implementation behind the interface there should be no changes to any one else's code.
In C and C++ this means a separate header file or namespace that knows about your internal gore - nobody else need know or care.
.NET C# makes façading easier.
Use a modern environment. Bin VS6 and get stuck in to C#. And trash that 286 and get a modern machine while you're at it!
Early delivery of functionally incomplete modules. This is distinct from a rapid prototype with throw-away code. These early previews have modules have quality tested code.
If your code need to be chopped out then chop it out! It helped you understand the problem: it served its purpose - now remove it.
Don't be afraid of refactoring! As you understand the problem – so you will refactor.
Yes and no. A couple of engineers worked with me and and adopted it.
But mostly NO. Most of the development staff are ingrained with a the waterfall approach. They write the specs; expect the specs to be read and understood by the customer; implement the specs;.... customer gets late delivery, and not what he expects.
This is the way we were taught at college - Agile is perceived as a way of cutting corners, lacking discipline, hacking, reducing documentation.
I hope that I and my Agile colleagues will infect the rest. I do know that forcing them down this road would be totally wrong!
I like the word "infect".
I guess this is a big advantage of being a contractor - you move around and pick up new ideas - that's great!
Documents I enjoy writing are those that will be read. (User manuals, deployment guides, release running notes, with staged rollbacks.)
I don't like test documents. What's more to say than: "Run the tests. If they pass the tests have passed, else they haven't passed; inspect the code to find out why a test failed."
If I cannot visualise the reader as I write the document - I'm doomed. (I keep a picture of the persona in my head: a secretary for the user manual; a support engineer for the deployment guide.)
I do like diagrams! (Shame about Visio!)
An electronics hardware background helps.
Have you experienced the final layout checking before a batch of PCBs is ordered? Now you know that you should order 5, and get them built up and tested, but there's pressure to save time and money and order a bulk run. Not too sensible, but you're amazingly thorough and scrupulously careful with each pad, via, trace.
If you get it wrong there's the visible re-work "bodge wires", or the penalty of having to wait for another batch of PCBs to be made up.
With software you can test and validate your design in stages. If a unit test fails, it's usually fixed very quickly. Psychologically nobody needs know you screwed up. Hardware screw-up's are more visible.
With hardware you have the fun of inventory. How non agile is that? Volumes get you better pricing. Use the same component many times on a design helps with cost, and reduces the number of different component bins.
Is a component about to be withdrawn? Do you buy n-thousand? Do you start a redesign?
Software has no inventory. You could include discs and manuals and packaging. The cost a fraction of the end user price - a mere trifle.
Hardware amounts to 1/3 of the end user price - so it's pretty important to get right.
Is this related to Agile? Yes - in that you have to be disciplined. No - hardware design usually follow a Plan Driven iteration that common across all hardware projects.
No, not in the sense of a good birching.