|Is this a representation of your system architecture?|
What does Incremental Design actually mean, how does it come into being and what are the consequences?
In the most positive world, an incremental design has not only been tailored to the practical need of business, but constantly adapts and evolves, so that the system architecture smoothly covers every need.
In practice, oftentimes unenlightened teams consider incremental design as absolution for failing to plan the long term.
Let us look at the example of the power supply of Ho Chi Minh City you see above:
Whenever someone needs a new electricity line or a current line is broken, the city workers quickly lay out a new cable and the need is met. Just drop the city a call and you will have a working solution within a couple hours! No waiting, no queuing slot, no formalities - just fast, working solutions!
That's agile, isn't it?
Practiced agilityWhat we see is an organization applying some agile values and principles, delivering results at a high pace for many years already: It's great!
Let's look at the team of electricity workers applying agile values here:
- Working software (power supply) over comprehensive documentation
- Customer collaboration over contract negotiation
- Responding to change over following a plan
Get the customer supplied with electicity comes first and foremost. The Definition of Done clearly contains "Customer can use electricity", management, bureaucracy and quotas are secondary.
If a line malfunctions, the location of the source doesn't permit for more cables, no problem: No job will be left undone. Just lay another line!
Now, let's look at the Agile Principles applied:
Our highest priority is to satisfy the customer through early and continuous delivery of valuable software.
- Welcome changing requirements, even late in development. Agile processes harness change for the customer's competitive advantage.
- Deliver working software frequently, from a couple of weeks to a couple of months, with a preference to the shorter timescale.
- Business people and developers must work together daily throughout the project.
- Build projects around motivated individuals. Give them the environment and support they need, and trust them to get the job done.
- The most efficient and effective method of conveying information to and within a development team is face-to-face conversation.
- Working software (power supply) is the primary measure of progress.
Yeah, there are a few Agile principles not so well applied, but we'll get to that later.
The Not-So-Agile partAs in any agile team, there is improvement potential. You just need to look at the picture above and you will see some potential.
The first thing that will spring to mind: How do they locate a defective line?
Short answer: You don't need to, when laying another line is cheaper than fixing the old line.
This is something you will also often see in software development.
It is a truism that adding a new, miniscule element to the architecture which fulfil the business need is oftentimes significantly faster than analyzing the fitting place, then designing and implementing only the minimal possible change.
We call this "local optimization".
Why is local optimization a problem?
Because in the long term, there will be nobody in your organization who is capable of telling exactly what each element is doing, and because in the end, the same thing will have been done hundreds of times - in nearly identical fashion!
Each newly laid electricity line not only fulfils it's job, but also keeps the existing lines stable: How can this be bad?
Well, first you have to think that probably 90% of the cables you see in this picture could be joined into one cable. Not only would the cityscape look more beautiful (are you really a developer who doesn't care if your code looks terrible?) but there is a problem at scale:
Yes: 10 parallel lines work. 50 parallel lines also work.
But once you hit 1000+ lines, good luck controlling the Electric Fields ...
The same happens in software design: Growing complexity is no problem until you end up with interferences which stem from an uncontrollable amount of sources. This is typically the point where "emergent design" turns into "emergent chaos" and business comes up with a good case for system decommissioning!
The solutionThere is an Agile Practice which is sorely needed to prevent this kind of disaster: Refactoring.
If you do not want your system design to resemble Ho Chi Minh City's power cable design, here is what you need to do:
Yes, it is sometimes OK to implement "quick and dirty" fixes to supply the business with the needed solution. But you should never consider a job "done" when business can work. You should consider it "done" when you cleaned up the mess.
Refactoring, ideally, should come either instead of "quick and dirty" or in the timespan between the first passing of acceptance tests and delivering the solution to business ("Red-Green-Refactor").
There are some situations where business criticality (for instance, human life depends on it) prohibits turning "quick and dirty" into a more beautiful design.
However, this should be noted in the backlog and scoped for cleanup at the nearest possible point in time.
Let's go back to our power cable example:
A second cable is totally fine and does not warrant refactoring, it's actually more failsafe!
A third doesn't either.
But when I come to a place where there are already five or more lines in place, I should come back to the office and put a mark in the backlog "Too many lines here", so that the next time, I move out, I don't only lay one new cable - but I lay 1 new cable in a fashion that I can decommission 4 cables, so the total amount of cables will be 2!
We call this technique "Optimize the Whole", and it comes from the Lean set of practices.
Do this in your software design, too:
Once you encounter a piece of code which looks like a tangled mess already, choose the closest feasible point in time (ideally: now!) to untangle the mess and decommission superfluous code elements.