“What a stupid design! You are singlehandedly responsible for the destruction of our ultimate weapon and battle station!” said Vader to the guy who put the exhaust ports on the Death Star. We might have designed a complex and flawed architecture for our software and survived without being choked by Darth Vader. But, how can we architect better software.
Before we dive in, let’s ask ourselves, “What do we mean by software architecture?”
- Non-functional requirements?
- High-level decisions and abstractions?
Here’s a low-level description that I like:
All architecture is design but not all design is architecture. Architecture represents the significant design decisions that shape a system, where significant is measured by cost of change — Grady Booch
And here’s a high-level description:
Architecture is the decisions that you wish you could get right early in a project, but that you are not necessarily more likely to get them right than any other — Ralph Johnson
What makes good software architecture?
1. Change should not be expensive
As the project moves forward, introducing changes should not be expensive. If the cost of changing or adding a new feature is high, it would take a longer time to release your software. In some cases, you may be unable to add a new features due to the constrains of the architecture.
2. It should have a feedback loop. It’s a cycle.
Architecture is a hypothesis, that needs to be proven by implementation and measurement — Tom Gilb
Architecture is an expression of an idea. Your job is to test the idea. Prove that it works. What you can build is influenced and constrained by how you build it…and vice-versa. It’s expensive to know everything upfront. You need to be okay with going back often and making changes as you move forward with the project. Architectural thinking is based on knowledge, which requires learning. Learning occurs throughout a software development project. Development increments should be based on functionality rather than component structure.
3. Make it agile and lean
Agile thinking emphasizes teamwork and response to change. Lean thinking focuses on the elimination of waste and improvement of flow. Again, making all the significant decisions up front is not responsible and if architecture is a hypothesis, we should use an empirical approach to test it. Sustainable agility requires good architecture; fast initial development does not — these are often confused.
4. Aim for sooner rather than faster
But what’s the difference? To illustrate, imagine you and your friend decide to do a road trip in two separate cars. While, your friend decides to use the GPS navigator, you decide to “wing” it. Both of you decide to leave point A at the same time and meet at point B using different routes.
While you may drive a faster car, if you get lost while driving to point B, your friend might reach sooner than you.
5. Work in smaller teams to produce good software
Today, we suffer from an almost universal idolatry of giantism. It is therefore necessary to insist on the virtues of smallness — where this applies . — E.F Schumacher.
The bigger the team, the harder it is to be flexible. Having more people on a project does not mean that the project will be completed sooner. There is no linear correlation.
Bigger teams require more communication. When there are more points of communication, the original message can be lost or become inaccurate between the source and receiver.
Once at an Amazon offsite, managers had the reasonable-sounding suggestion that employees should be increasing communication with each other. To their surprise, founder and CEO Jeff Bezos stood up and announced, “No, communication is terrible!”
This stance explains his famous two-pizza team rule, that teams shouldn’t be larger than what two pizzas can feed. More communication isn’t necessarily the solution to communication problems — it’s how it is carried out. — Janet Choi
Software development does not have economies of scale.
Development has diseconomies of scale — Allan Kelly
6. Do not use speculation to add extra complexity to the architecture
Use speculation and future requirements to decide between design alternatives. Use past change to forecast future change — look for change hot spots and high defect density. Structure the system with respect to rate of change and (un)certainty. Change is often the only constant.
The ability to simplify means to eliminate the unnecessary so that the necessary may speak — Hans Hofmann
Architectural definition is something that answers three questions:
▪ What are the structural elements of the system?
▪ How are they related to each other?
▪ What are the underlying principles and rationale that guide the answers to the previous two questions?
7. Always think of 3 things that might go wrong
Nothing is more dangerous than an idea, when you have only one idea — Émile-Auguste Chartier
We should always understand the context and richness of the software that we are designing. Based on that, we should propose at least 3 things that might go wrong. We need to validate our hypothesis on these potential failures or errors. When we are making progress developing our software, we are gaining more knowledge from things that work and don’t work. We should be comfortable starting from the beginning if we noticed a flaw in the architecture.
Architectural questions and considerations when redesigning our software:
▪ Where are the defects? Is there a reason they are distributed that way?
▪ Where are the ‘hard bits’? What makes them hard?
▪ Where are the ‘easy bits’? What makes them easy?
▪ What keeps changing? Why?
▪ What stays still? Why?
If you can’t think of three things that might go wrong with your plans, then there’s something wrong with your thinking — Jerry Weinberg
Architecture is about codifying knowledge. Good architecture should be flexible. You should be able to iterate on your architecture until you get a Minimum Viable Product. Any changes in the future should not be costly. Keep it simple. Adding more developers to a project as the project grows will not automatically speed up the project. Don’t spend too much time at the beginning designing; instead, just build it and see what happens. With good architecture, you can make mistakes continually and still make progress.
Sustainable development is development that meets the needs of the present without compromising the ability of future generations to meet their own needs — The Report of the Brundtland Commission
Interested in learning more about software development? Read my other article on: 7 Lost Principals of Continuous Delivery
I met Kelvin Henney at the GOTO Chicago 2018 conference. Kevlin Henney is an author, presenter, and consultant on software development. He has written on the subject of computer programming and development practice for many magazines and sites, including Better Software, The Register, C/C++ Users Journal, Application Development Advisor, JavaSpektrum, C++ Report, Java Report, EXE, and Overload. He is a member of the IEEE Software Advisory Board. Henney is also coauthor of books on patterns and editor of 97 Things Every Programmer Should Know.