Simplicity and Complexity In Software Development
Simplicity is not always a good thing, and complexity is not always bad. Context must be analyzed for the accurate assessment.
Confusion and Consequences
Many times, people involved in software development processes try to use simplicity or complexity of the outcome as an input in making decisions. Based on the assessment, they can make design, coding, testing, architecture, and deployment related decisions one or the other way. Over time, these decisions often bite back, uncovering problems which had to be thought of and addressed much earlier in the software lifecycle. How can this be explained if the assessment happens all the time in advance?
Answer is not straightforward but agreeable - probably the assessment of simplicity vs complexity was inaccurate. Root cause is the fact that simplicity and complexity have slightly skewed meanings in software development field, or rather - they have two sides. Specifically, their positive or negative impact is not straightforward to see if we blindly decide that simplicity is always good and complexity is always bad. True answer is that the impact should be gauged case by case basis.
I will construct the rest of the article as an example of an e-commerce software development project. Events will be ordered in a chronological order, thus ensuring that I cover numerous common pain points instead of missing them. On the way, I will be analyzing and calibrating our view of simplicity and complexity, instead of letting it flow as it would otherwise do.
My hope is that at the end of this article you will somewhat redefine your thought process around simplicity and complexity, by agreeing that the former is not always good, and the latter is not always bad.
Your task is to notice how I mention "simplicity" and "complexity" in various contexts, and what I mean by that. To make it easier, I will emphasize these words every time I use them.
Let's get to it.
Large E-Commerce Software Development
* * *
A group of people gathered to develop an e-commerce system for a large enterprise. Their task was very simple - sell all kinds of products that the company manufactures. To do this, the team of highly skilled, technical people was assembled in order to tackle all the technical complexity that the system would address. There was not much domain or functional expertise requested - because the e-commerce is already a well known domain to everybody, anyway.
* * *
The story above describes a simple task with technical complexities. At first sight, everything looks normal. We have a simple task and thus we don't need much expertise in e-commerce. But we do need to setup complex technical infrastructures for the system to function, so we do need a strong focus on technical side.
This is a first indication of infrastructure-driven architecture - something that leads to building a system which can function technically well, but will not be able to serve the business as well. There will be an inevitable disconnect between how domain experts think of their business and how developers build it.
While the task may seem functionally simple to technical people, it will almost never be the case for non-technical people. Every successful business is unique and proprietary in some way, which is what gives it a competitive advantage on the market. If there was no uniqueness, success and failure of the similar businesses would be relying on a bare fate. Businesses don't run this way. A successful business has a unique way of solving the problem, or at least a unique way of executing the solution. So the initial simplicity is just a confusion, which has tricked the whole project into the questionable direction. A functional complexity was what needed the most attention, but technical people naturally overlooked it.
Furthermore, technical complexity is clearly overestimated. Very unlikely that the technical complexity could outweigh the domain complexity. After all, e-commerce is not a technical domain. In such domains, domain complexity is usually higher than the technical complexity, that's why more focus should be on the domain, rather than on solving technical challenges all the time. So the technical complexity was not so bad as it seemed - since it was overrated.
* * *
The technical team architected a scalable, message oriented software system, which was able to support product selection and purchase paths online. Because these were technical people with little or no interest in focusing on the domain expertise, no modeling or collaboration-focused approaches were used (no DDD, no Event Storming, no ubiquitous language, no hands on modeling). Also, no thought was given to strategic large-scale designs to determine boundaries of various problems addressed by the business (no Context Mapping, no Bounded Contexts). Instead, technical designs were created which could support the domain needs hidden underneath. On the surface, they developed several tools that would feed the system with flexible product configurations, data warehousing, and settings/properties management for turning on or off components on the screen.
* * *
Second part of the story talks about both complexity and simplicity. There is a technical excellence and simplicity in achieving technical goals - because the system seems scalable and very well built - it is simple to convince a technical person that this is the best way to go forward. It simply is the best architecture they could come up with, and everything together makes so much sense. This simplicity is not for everybody though, so it's not a very good thing. While technical people could easily manage the system, how likely is it that non-technical people will also be able to do that?
There is complexity for non-technical people, literally everywhere. Now they need to learn all these tools, even if developers will keep interacting with these directly. Non-technical people, especially domain experts, will need to rethink how they see their business. They need to digest the mapping between business (how they work) and technical vision (what developers have delivered to them). But how come? domain experts know the business better. Why should they rethink the business from technical standpoint? This swallows much energy which could be directed on strengthening the business competitive advantage. Now the situation has become a completely different ballgame - as if the competitive advantage is in the technical excellence and not in the business execution anymore. Such technical solutions make business's life harder and slow down the innovation in execution. I know that technical people would disagree (I deal with it every day) - "there is nothing so complex in the architecture" they would say... So, clearly, the complexity is for non-technical people only.
When simplicity is achieved for technical people by technical architectures, complexity is delivered to business experts. Negative impact of such architectures far outweighs the technical goodness of them. This is a hint that functional simplicity is much preferred with the cost of some complexity to technical developers. This cost can easily be bought out with a proper learning curve. Ideally, software system should be simple for domain experts, and should as well be simple for software engineers building it. This can be achieved by mastering the right technical skills (while focusing on them would take us too far right now, I mentioned couple of them above).
* * *
(story continued )
The team developed a system which was deployed to production environment.
Everybody wanted to keep developers' lives simpler, so they put together a production support team, who would fix urgent issues in the production environment. Meanwhile, developers could focus on adding more features to the system.
Over time, the system grew and it started solving more and more problems. More developers were brought into the team, but the team became too large to be called "a team". So they split teams. For simplicity, the codebase was kept the same and shared across several teams. They just agreed that they would be careful when touching the same code. This was much simpler than splitting the codebase and applications between teams.
* * *
As we see, much focus was dedicated towards keeping developers' lives simpler. It seems they have managed to do so. But is it a good thing?
If developers don't support their own application in the production environment, they will never build it so that it does not need to be supported. This is a prescription for having a dedicated production maintenance team forever. When the actual developers have to deal with the issues in the production environment, they will ensure such issues won't happen again. So, by simplifying their lives, we are not doing any favor to the company or the quality of the software. We are just making matters worse.
Codebase was shared across several teams for the sake of simplicity. But is it really simple if every code change requires so much careful engineering? Yes, it's complex to refactor, it requires skills. But that complexity comes with great payback - you end up having autonomous teams, each able to evolve and innovate independently. Without autonomy, too much overhead goes in endless coordination of efforts, breaking each other's code, everybody releasing together, and so much more unbearable noise.
Finally, it is complex to learn all the necessary skills to build the quality software, one which is aligned with the business goals, by helping the company gain competitive advantage in the business area it operates.
Just because it's complex does not mean it's bad. As we have seen so far, using simple technical skills results in hard to maintain software. Making software complex to business users kills the potential of the positive impact that the software can have for the business.
Now, do you still think that simplicity is always good and complexity is always bad? Maybe this is the controversy that Leonardo da Vinci left for us?
Simplicity is the ultimate sophistication.