Although it’s a broad generalisation, Agile software development practices can be broken down into management practices and software design practices. The management practices are things such as short iterations, continuous integration, pair programming, programmer task estimation and co-location. The software design practices are things such as Test Driven Development, the SOLID principles and design patterns.
A common pattern I see repeated in many organisations is that the management principles are understood and adopted, while the software design principles are mostly ignored.
While the management practices may make for saner project management, they won’t do anything in themselves to improve the quality of software being produced or the productivity of the team.
Software development has a core pathology; you can see it on almost any project over a certain size. As the code base increases in complexity, the cost of adding a feature increases and defects proliferate. Often this is accompanied by ever increasing problems with build and deployment and de-motivated and unhappy developers.
Once the software gets part a certain size and age, it becomes almost un-movable and a real hindrance to the business. Often the response is to start from scratch, but this just makes things worse as the new system gradually goes the same way as the old, and in many cases never fully replaces it. Then there is the additional task of integrating the old and new systems, usually as a ‘temporary measure’.
Of course, building a robust scalable Service Oriented Architecture (to integrate the new and old systems) brings its own challenges. A team that failed to build a an initial scalable application will often fail in this task too. Soon more and more of the team’s resources are devoted to making the old and new systems talk to each other. More resources are applied and less is achieved.
The end game is often a static lock, where the business cannot move forward or react to changes in the competitive landscape because the software it relies upon cannot adapt. The software team becomes a large fixed cost that simply drains the bottom line rather than adding any real benefit. Usually the only agility the business retains is by working around their core systems and relying on more primitive forms of record keeping such as the humble spreadsheet or Access database.
I first came across the description ‘Agile’ in relation to software development by reading Bob Martin’s classic, Agile Software Development. Martin spends some of the book discussing Agile management techniques, but the majority of the text is devoted to Agile design practices including several detailed coding case studies.
Agile software design practices are the distillation of the collective experience of the software community over the past decades. A lot of very clever people have been struggling with the problem of how to avoid the pathology I described above. These practices are in no way a complete answer to all the problems we face with building large scale applications; the industry is constantly learning how to do this better; but they do add up to a sizable body of patterns and practices than can make a significant difference to the success of a project.
You can buy a whole library of books on writing better software, and if you are serious about it you should. But as a taster, here is a incomplete list of some Agile software development principles that come to mind as I write this:
Never rewrite the system. See The Big Redesign In The Sky.
Don’t repeat yourself ever. DRY
Refactor relentlessly (see above)
Only code what you need now (You Ain’t Gonna Need It: YAGNI)
Do the simplest thing possible.
Keep methods small (less than 10 lines of code). Keep classes small and with a single responsibility (see SOLID below).
Keep methods simple (low cyclomatic complexity).
Decouple components from each other at every scale (class, service and application).
Only allow components (classes, components, services, applications) to communicate through well defined interfaces.
Decouple your application into well defined tiers. Don’t mix business logic, UI logic and infrastructure.
Use design patterns. Someone has probably solved your problem before.
Don’t write any code except to make an automated test pass. This is Test Driven Development.
Avoid code generation. But automate anything you can.
Use the right tool for the job: XML is not a good programming language, TSQL is not a good place to encode business rules.