What agile projects really make agile is best formulated in the Agile Manifesto. Among others the following principles are included:
- Deliver working software frequently, from a couple of weeks to a couple of months, with a preference to the shorter timescale.
- The most efficient and effective method of conveying information to and within a development team is face-to-face conversation.
- Working software is the primary measure of progress.
- Agile processes promote sustainable development. The sponsors, developers, and users should be able to maintain a constant pace indefinitely.
- Continuous attention to technical excellence and good design enhances agility.
- Address the biggest risks first.
But before I explain, let me first tell you a little bit about the project. It concerns maintenance of an existing system that is over more than five years old. The system has been build using Oracle Designer / Developer, with a lot of PL/SQL code in the database of which a considerable part enforces rules and regulations. Rules and regulations being changed significantly was the reason to start the project and make the system adapted accordingly.
The major challenges we focussed were these:
- A first increment should go into production before January (it was end of October when I got first involved so we had only two months).
- The PL/SQL code was set up using a lot of (what we in retrospective may call) bad practices, like one huge package that 'does it all' with tightly coupled procedures of which many had no clear responsibility.
So what you gonna do? Well, first of all we (meaning a team of 3 developers, a client-project manager and ambassador user) decided to meet on a daily basis to monitor the status, exchange information and address issues as soon as they emerge. In this setting we made up a high-level MoSCoW-list, determined the dependencies between the requirements, and decided upon their prorities (primarily based on dependencies and biggest risks first). Using this as input, we then thought of an approach how we best could adapt the existing system in an incremental way. We created a low-level MoSCoW-list with a scope of two weeks, delivered what we produced and based on our experience created the next low-level MoSCoW-list.
Sounds easy, wouldn't you agree? Yeh, right...
We are dealing with people here and in general people have a few pretty persistent habitst that must be dealt with. Like many people find it counter-intuitive to design and implement functionality just to achieve a foreseable goal, knowing that in some near future they probably have to change it as a result of evolving insight. Main reason is that we have a tendency to try to do it right the first time to prevent needing to change code later on which just seems like overhead. Unfortunately experience shows almost none of us is capable overseeing everything that needs to be taken into account upfront. Discrepancies between vision and reality emerge the minute we start to build the real thing and especially become apparent when end-users are confronted with it.
Another tendency we have, is starting with a couple of simple things just to get a sense of achievement, while postponing the more complex issues, hoping they kind of solve themselves as time goes by. But those issue are the ones with the biggest risks associated with them and when they do not solve themselves, it often is too late and you find yourself being in big trouble. I have never done research to find out, but I do believe that addressing high-risk issues too late is the major cause of budget overrun, deadlines not being met or deliverance of considerable less functionality than planned for.
So what agile methods therefore promote is developing small increments that are delivered frequently. This will prevent us from going the wrong direction for too long as we will notice it soon after that happens. To prevent that changing things later indeed results in a lot of overhead, we maintain a simple design by creating the simplest thing that could possibly work. Whenever the design starts to get complex, we refactor to make it simple again. To allow for refactoring without breaking the functionality, we apply unit testing to prove the system still works afterwards. To reduce risk we ensure that the code one person creates works with to code of others, by continuously integrating everything we produce. And wherever feasible, we start with those aspects that are the least clear to us how to proceed with, to find out as soon as possible how they can be resolved and what the impact on other aspects is.
All this is not just a nice theory. We did just that and proved it works!
We consulted each other at least once a day, keeping eachother on track with maintaining a simple design and refactoring when necessary. On an average we delivered every two weeks and from increment to increment added new functionality while at the same we improved the existing poor architecture. The result is a system that not only does what it is supposed to do, but which also is based on a solid architecture with excellence through simplicity!
Only time will tell, but I have a strong feeling that we considerably reduced the costs for maintenance and perhaps made that the system will survive for yet another five years.