Sources of Complexity

Software can get and often does get complex very fast. Many engineers and teams often don't understand the effects of some decisions resulting in extra Complexity. For this blog post, I want to explore more of these sources of Complexity. We can, in fact, only improve what we understand. Lean Thinking often tells us that we need to understand to see waste; otherwise, we cannot avoid it. Complexity can be generated thought of many sources. Nowadays, every single team is aware of technical debt. Technical debt is, in fact, too late, you can only fix it by refactoring. However, if you do teach your team to see and understand the Complexity, you will still be creating debt. It's impossible to have software that is 100% debt-free, however for sure, we can prevent a reasonable degree of debt by understanding software complexity and manage it proactively with proper education and carefully taught. Managing debt is a duty that every software product and project has. We need to act tactically, proactively, reactively on all fronts. Let's get started. 

7 Sources of Complexity

There are many sources of Complexity. I want to focus on non-conventional ones or non-obvious ones. You might not consider then as sources of Complexity at first glance. Hopefully, after some explanation, it will make sense. At the end of the day, there is only one ultimate source of Complexity. Complexity could be quickly boiled down to Ignorance. If you know what you are doing meaning, you understand your problems, you know your tools, you deliberately work on our culture complexity can be minimized. Let's see some other factors that often spark Complexity. 7 Sources of Complexity:

#1 Big Successful Enterprises 
#2 Technical Events
#3 Organizational Culture
#4 Convenience 
#5 Binary Coupling
#6 Contract by Accident
#7 Concept Coupling

#1 Big Successful Enterprises 

Many C-level executives down here in Brazil have the costume to visit other companies. Unfortunately, they dont visit companies like NuBank, iFood, Magazine Luiza. Often they go to old but yet super Succseful traditional, waterfall-based companies. I dont need to name these companies, but for sure you know lots of them. I see it so many times in the past. Believe me, this still happens. OH, I visit my CIO friend from company X, and they are doing the latest vendor O ESB, and we should do it too. Big traditional successful companies go visit other big traditional successful company and guess what? They copy the software development methods and stacks. So this creates lots of complexities and debts. Because if company X is successful, you can just copy they stack + processes, and we will be too. This is not the case, but it still happens a lot. 

#2 Technical Events

This might sound wrong but is also a source of HUGE Complexity. Often Tech events can be significant because we can learn what other companies are doing. However, usually, it couple be a source of Envy where you go there and just say: OH my company is not doing Docker, I should be doing Docker now. You might think this is crazy, but this is very true. Many engineers just want to do things because if what other people are doing and really dont understand what problem they are trying to solve and what pros/cons each choice generates. I love tech events, but I have a conscience about what I should do and not do for each project/customer. For better or worst, it creates a substantial sociological wave of pressure, like fashion. However, the tech should not be about way but often is. 

#3 Organizational Culture

Organizational culture is another source of Complexity because often, your company culture could be quickly pushing for:
 * Just worry about features and dont do proper architecture and design.
 * Hiring the cheaper contractors -- who will produce more tech debt.
 * Build Frameworks and Shared Libs -- So Product engineers dont need to "think" just use frameworks.
 * Push too much on estimates(deliver on dates) -- resulting in no discovery and no proper requirements -- guess what happens? Lots of Complexity in the software. 

Easily the post could be just about the organizational culture, which is a huge source of technical Complexity and, therefore, debt. 

#4 Convenience

This is another tricky one. You might think that Developer Experience(DX) is always a good thing. However, it is not. Convenience has a price—idiomatic means couping. As more convenience your engineers/developers have as more coupling, you gonna have it. Typing should not be an issue for any engineers/developer. Often frameworks, libs, and vendors are picked up because they are "loved brands," and thats wrong; it should be for other reasons. Often having more convenience happens because convenience is considered productivity. If you look in the long run, it is not always accurate, and convenience can result in Complexity, coupling, and debt. 

#5 Binary Coupling

Binary(in the form of a framework on liberty) is a more natural form of reuse. However, you need to keep in mind  2 essential things. First is the fact that you will need to maintain everything public. Second that you very likely o have 3rd party dependencies.  3rd party dependencies are often silly or straightforward at first glance, but as time pass you might have a distributed monolith because of them. Binary coupling makes everything harder, and as much as you can, if possible, you should leverage Service, Tools, Platforms, Sidecars, and other forms of distribution, which are beyond binary.  It's possible to have libraries and still dont have bad coupling or acceptable coupling, but that requires thought and care. 

#6 Contract By Accident

Many engineers believe that public contract is only their REST interfaces. Thats is not 100% sure. Everything visible to your consumers is your contract. Contract by accident is an excellent source of Complexity because it is an excellent source of coupling. You can consider sources of tables, configuration files, classes, aspects, pojos, anything that people might be sing directly.  Binary coupling is a tremendous potentializing of Contract by Accident. Botton line is: the less you show, the less coupled you are therefore less Complexity. Hiding is an essential concept in software engineer, especially in distributed systems. 

#7 Concept Coupling

Concept Coupling means there is one concept, and you coupled with another. Therefore you create confusion with is a HUGE source of coupling. Legacy is the software that is in your company before you. Often associated with harmful software. A monolith is a unit of deloyment. Monolith does not necessarily mean that it is terrible. However, the industry, coupled with these 2 things together: Legacy == Monolith. Therefore all monoliths are bad. Thats not true. Concept coupling is really bad because it blinds you, and you end up just seeing one side of the coins, and guess what? It's a vast source of Complexity, therefore, debt. 

Complexity can be induced by many forms. It's important to be aware of these sources of complexity but also by applying thoughtful design process by applying questions likes:
 1. What requirements do we really have? 
 2. What pros/cons we do gain if we go approach A vs approach B? 
 3. What principles do we want to leverage?
 4. What we are really gaining by the X method or Y framework or Z process? 
 5. Are we doing something because it is better for the company or because someone asked us? 
 6. Are we going X because we are envy and want to be cool or because we really thought about and at the end of the days the benefits are bigger than the drawbacks? 
 7. Can we see drawbacks on the Y approach or Z solution? 

Software architecture and design are not easy however we need to start being more thoughtful about our choices therefore we can reduce complexity and the whole business will benefit in a long rung. 

Cheers,
Diego Pacheco

Popular posts from this blog

Kafka Streams with Java 15

Rust and Java Interoperability

HMAC in Java