My mom used to say this to me as a child: “First think, then act.” I often think of this motto ‘look before you leap’ when creating software solutions.
In the past, we used to develop using the so-called waterfall method. In this highly sequential development process, much emphasis is put on elaborating the software architecture and/or design to a great level of detail before any software is actually built.
Nowadays, we use the agile project approach for developing software. In this approach, much emphasis is put on iterative development, where every (agile) development cycle contains a small part of requirements gathering, design, build, test and go-live.
In the world of today, with its rapid changes in both the business world and the technological world, with ever increasing customer demands, this agile software development is absolutely needed. Although there are still waterfall software development projects today, for good reasons, most of our software development projects use agile development.
We cherish the fruits of the agile development process. However, we also see a major pitfall. In every agile sprint a design is created for all functionality that is part of that specific sprint. However, there is no overall architecture or design. The design of every sprint within a project can be as optimal as possible, but the overall project can still end up with a suboptimal overall solution.
Suppose you use a navigation system to drive from city A to city B. If you plan your route by planning the routes between all intermediate villages, you will probably end up with a route that only uses local roads. Only if you take the overall start and end location into account, you can see that you can use the highway, which is of course much faster.
Developing software without an overall architecture, or at least an overall design, can yield suboptimal software, concerning performance, understandability, maintainability, extendibility and reusability.
FINDING A WAY OUT ….
The question is how we can use agile development while avoiding this pitfall? We can of course just start with an architecture and/or design for the entire application we want to develop, before starting with our individual sprints.
The Agile Manifesto states ‘Value Responding to Change more than Following a Plan.’ One reason for this statement is the experience of many waterfall projects where a fairly detailed design is made, taking a long time and much effort, while in the end the usage of this design turns out to be very limited. The limited usage of the design is mostly due to changing environments and requirements, or due to insights that can only be obtained while actually realizing parts of the software (either due to technical details or future-users insight in the final application). This is what we want to avoid by creating only a design for the part of the software that is realized in one sprint.
We still want an overall plan (architecture, design), but we don’t want to end up with an all too rigid roadmap, that costs too much. Our experiences teach us that it is helpful to stick to a famous principle of Albert Einstein: “Make everything as simple as possible, but not simpler”.
So we still want to create an overall design before jumping into the different sprints, but we want to keep the design as simple as possible. The big question now is: just how simple is that? How far do we need to elaborate?
In terms of the aforementioned navigation system: we need to look to the overall map in combination with our starting point and our destination, in order to be able to detect the possible use of the highway, instead of local roads only. We do not need to know beforehand the exact speed limits for the different parts of the highway.
Translated to IT this means we do need to see:
- the dependencies between the different parts of the system that will be developed in the different sprints;
- possible reusable parts across the different sprints;
- whether the partial solutions that the different sprints create together form an optimized solution for the overall goals.
USE BASIC DESIGN PRINCIPLES
There are many different ways to create such an overall design, and split the needed overall development effort into different sprints. Essential in our view is to stick to the basic principles of software design: modularity, encapsulation and orthogonality.
Modularity stands for splitting the software that has to be developed in different modules/parts, based on high internal coherency and low external coherency. Encapsulation stands for only using a module via clearly defined interfaces (encapsulate the modules). Orthogonality stands for keeping functionalities that do not have any inherent relation, as separate as possible (do not introduce unnecessary dependencies).
Prof. Dr. G.A. Blaauw, a prominent computer pioneer and expert in the architecture and design field, already showed way back in the last century, that using these principles strongly enforce the reusability, understandability, maintainability and extendibility of the eventual solution.
These three design principles are still a major beacon when creating an overall design. Keep it as simple as possible, and at least stick to these principles as a basis.
ADJUST IF NEEDED
Let’s look to the navigation system example again. Of course, if a major traffic jam occurs on your route, you adjust your route. You might for example leave the highway and use the local roads after all.
When creating an overall design before starting with the agile development of the software, this (high-level) overall design will also have to be adjusted if needed. Reasons for changing the overall design during the different sprints can for example be:
- Changing environments;
- Changing business requirements;
- Changing IT environments, e.g. new or changing interfaces to other IT systems;
- More in-depth knowledge, obtained in one or more sprints;
- due to technical details not known before;
- due to future-users insight in the final application;
Explicitly checking whether the overall design needs adaptations during the different iterations in the agile way of working, meets the agile manifesto: ‘responding to change’ over ‘following a plan’.
In this way, we keep the balance between ‘working with an overall design’ and ‘agile development’.
Look before you leap. Use an (high-level) overall design, even when working agile. But keep it simple! And adaptable.
Look before you leap. But do leap! And keep looking, while leaping!