Do you develop a complex digital system? How do we define a complex system and how should we approach it when we want to develop it further?
I usually say that anything that can induce strong feelings inside us as human beings when interacting with it is to be seen as a complex system. To exemplify this, I often say that a part of a complex system could be anything, like a network printer for example – and for illustration I use the picture below from the movie “Office space” – the scene when the characters use excessive violence at a network printer out on a field. Anything that holds this capacity to touch our emotions on such deep level manifests a part of a complex system. Like most systems are.
To further exemplify what I mean by a complex system we can also look at what happens when we interact with it as developers by telling stories of various types of bugs that we all stumble into and how their behavior resemble characteristics of physics. Do you know how to define a heisenbug, mandelbug or a schrödingbug?
A Heinsenbug is:
[from Heisenberg´s Uncertainty Principle in quantum physics]
”A bug that disappears or alter its behavior when one attempts to probe or isolate it”
a Mandelbug is (named after Benoît Mandelbrot’s fractal)
a bug whose causes are so complex it defies repair, or makes its behavior appear chaotic or even non-deterministic.
(or, in other words – the deeper a developer goes into the code to fix it the more bugs they find)
And – my favorite – the Schrödingbug (named after Erwin Schrödinger and his thought experiment):
“a bug that manifests itself in running software after the developer notices that the code should never have worked in the first place.”
The funny thing is that most developers laugh with a great deal of recognition when hearing of these definitions, and it helps us to understand the level of complexity in modern development. The vast number of dependencies we need to handle in development on a daily basis is difficult to grasp. As a matter of fact, it is so difficult for us to embrace the level of complexity that we often refuse to take in how complex it really is. When we observe a system of a certain level of complexity, many organisations and individuals try to break down the complexity into smaller entities that is easier to grasp and understandable. One common way to approach this is applying paradigms as a cloud native architecture with microservices or transforming the organisation into working according to Scaled Agile Framework. However, even if this in the short run seems to make thing easier for us to understand, this does _not_ lower the complexity on a holistic level. The level of complexity is the same because these microservices and development teams needs to coexist and work together in an efficient manner in the end anyways in order to provide an awesome (or awful) user experience. So how could we approach complexity in other ways?
People avoid complexity. Mankind wants to look at software development as something very simplistic. As humans, we feel a great deal of discomfort in seeing complex things for what they really are. Therefore, we tend to hold on to our mental models that describe software development as a mechanical craft, so that we can continue to use factory-based mindsets inherited from the industrial revolution where we as engineers construct, install and fine-tune cogwheels, wires, bolts and screws. This view that industry has taught us – and served us all well during the last century – is to be seen as the correct way to build a car, a bridge or a building – or for example this wooden marble machine that plays music with 2000 marbles (really amazing! – link to video).
But our digital ecosystems of today have become so complex that it transcends into something far more advanced than this beautiful machinery. This machine can create incredible music, but our digital system landscape can create far more experiences – and it can behave differently every time it gets stimulated – more similar to a digital organism that reacts in ways we often don’t understand or could foresee. It has the potential to offer a lot of amazing experiences for end users today in the endless touchpoints between the digital and physical. But of course, digital products can also create horrific experiences as well during the interaction causing a great deal of discomfort, anger and despair or in worst case injuries and even loss of life. And under the hood, it is source code that cater for that result. But when studying what ingredients, we need to add to the mix in order to enable those awesome capabilities, it starts to get far more complex than “just source code”.
Many development organisations of today struggle since they are stuck in the mechanical way of seeing development as “just source code” and that we as a dev organisation in a factory-based manner should “deliver” by getting all those development items to DONE and get the source code out there in our production environment. Agile is seen as a method to get the source code out there – faster. But does speed actually result in greater value for our end users? Many organisations start to understand this complexity on a deeper level but lack the methodology and approach to embrace complexity in a comfortable way.
How to make large organizations understand the gains of seeing things for what they really are – complex? For example – when trying to transform a legacy system landscape to microservices – it will become complex. To implement a new application for an entire organization of thousands of employees – is complex?
I have tried to talk about Cynefin framework, systems thinking, data driven development, digital twins, metrics driven development, dataOps, and even tried to talk about transactional development versus transformational development. But the message never really sunk in at scale…until…
But – let’s back up a bit. During my studies I took a break in my master´s in computer science to do something completely different. I took the opportunity to train as a medic in the Swedish Amphibious corps. The hard military training consisted also of theoretical medical studies at the University of Gothenburg, and a lot of practical experience from the emergency and surgery rooms of Danderyds medical hospital outside of Stockholm. During this time in my life, I assisted surgeons to stop bleedings in the surgery rooms, followed ambulance personnel when a young child went into seizure, observed during an autopsy and much more – and I never ever thought I would find any use of these learnings later in my professional life.
However, I learned one fundamental thing through all this – the human body forms a magnificent example of a complex system. Approximately 78 organs, 650 muscles connected through 187 joints and 206 bones – and it is all working thanks to 11 vital systems where circulatory, respiratory, nervous and digestive systems are just a few of them.
So – recently in my career I started to make use of my medical knowledge and vocabulary to put into use in software development inducing another narrative to frame development, test and QA in – stating things like:
– “We need to treat our entire system landscape as it was our patient – we must care for it and make sure our treatments are safe and effective. “
– “Development is like surgery – while we perform our digital treatment and operations, we must not forget to continuously monitor our patient”
– …and when I started to use terminology like sensors, monitors, treatments, diseases, diagnosis – people started listening and being observant on a much deeper level than before when I were talking about test scripts, reports, development items, bugs, and root causes.
As it turns out – people seem to understand and embrace complexity much easier if we see ourselves in the situation of how a doctor treats its patient compared to how a developer traditionally implement source code that gets promoted in production and executed by the user.