Fundamentals 21 min read

Why Software Complexity Grows and How to Tame It: From Tactical Tornadoes to Strategic Design

This article explores the nature of software complexity, its rational and sensory definitions, common symptoms such as change amplification, cognitive load and unknown unknowns, and contrasts tactical programming practices with strategic design approaches to help engineers manage and reduce complexity over time.

21CTO
21CTO
21CTO
Why Software Complexity Grows and How to Tame It: From Tactical Tornadoes to Strategic Design

Introduction

A doctor and a civil engineer argue about the oldest profession, and a software engineer walks in to ask who created the chaos, setting the stage for a discussion on software complexity.

What Is Complexity?

Two main definitions are highlighted: the rational metric introduced by Thomas J. McCabe in 1976 (cyclomatic complexity) and the sensory perception described by John Ousterhout, which focuses on how hard software is to understand or modify.

Rational Metric (Cyclomatic Complexity)

Complexity ranges are described:

1‑10 : clear, highly testable, low maintenance cost.

10‑20 : moderate complexity, medium testability and maintenance cost.

20‑30 : very complex, low testability, high maintenance cost.

30+ : unreadable, untestable, very high maintenance cost.

Sensory Perception

Complexity is anything that makes software hard to understand or to modify.

John Ousterhout emphasizes that complexity is a property of the software itself, not an accidental side‑effect.

Root Causes of Complexity

Ambiguity and dependency are identified as the two main drivers. Ambiguity makes code hard to read, while dependency spreads complexity throughout the system, eventually turning it into spaghetti code.

Symptoms of Complexity

Change Amplification

Change amplification: a seemingly simple change requires code modifications in many different places.

Typical example: a copy‑and‑paste style code base where a small business rule change forces edits across multiple modules.

public void pick(String salesId, String customerId) {
    long customerCnt = customerDao.findCustomerCount(salesId);
    long capacity = capacityDao.findSalesCapacity(salesId);
    if (customerCnt >= capacity) {
        throw new BizException("capacity over limit");
    }
    // ...
}

Cognitive Load

Cognitive load: how much a developer needs to know in order to complete a task.

When a framework is overly complex or a system is over‑engineered, developers must invest excessive mental effort to accomplish simple tasks.

Unknown Unknowns

Unknown unknowns: it is not obvious which pieces of code must be modified to complete a task.

In long‑lived projects, missing documentation and tangled code make it impossible to predict the impact of a change.

Why Complexity Arises

Taking shortcuts without refactoring.

Lack of craftsmanship and ignoring dirty code.

Insufficient technical ability to handle complex systems.

Poor hand‑over and missing product documentation.

Tactical vs. Strategic Programming

Tactical Programming

Focuses on delivering the fastest solution, often at the expense of long‑term quality. Characteristics include:

Fastest current implementation.

Minimal time spent on optimal design.

Each task introduces additional complexity.

Refactoring is avoided to keep speed.

@HSFProvider(serviceInterface = AgnDistributeRuleConfigQueryService.class)
public class AgnDistributeRuleConfigQueryServiceImpl implements AgnDistributeRuleConfigQueryService {
    @Override
    public ResultModel<AgnDistributeRuleConfigDto> queryAgnDistributeRuleConfigById(String id) {
        // ... implementation with many unchecked concerns ...
    }
}

Tactical Tornado

Almost every software development organization has at least one developer who takes tactical programming to the extreme: a tactical tornado.

A tactical tornado delivers immediate results but leaves behind a legacy of hard‑to‑maintain code, pushing the cost to the future.

Strategic Programming

Emphasizes long‑term value, incremental improvements, and an investment mindset (10‑20% of effort on design). It avoids unnecessary complexity and aims for sustainable evolution.

Architecture and Paradigms

Software architecture has evolved from monoliths to distributed systems, SOA, micro‑services, FaaS, and service mesh, all aiming to manage complexity.

Only three programming paradigms have emerged:

Structured programming – eliminates goto and restricts direct control flow.

Object‑oriented programming – limits pointer use and indirect control flow.

Functional programming – centers on λ calculus and restricts mutable state.

The SOLID principles (Single Responsibility, Open/Closed, Liskov Substitution, Interface Segregation, Dependency Inversion) are highlighted as essential design constraints.

Code Quality Myths

Comments do not make up for bad code – Martin Fowler

The myth that “good code is self‑documenting” is debunked; meaningful comments are still necessary to convey intent, naming limits, and design rationale.

Conclusion

Software complexity is an inherent property of any non‑trivial system. The goal of architecture is to minimize the human effort required to build and maintain it. Engineers should choose appropriate architectural styles, avoid over‑optimizing simple systems, and balance elegance with practicality.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

code qualitysoftware designsoftware complexitytactical programmingarchitectural patterns
21CTO
Written by

21CTO

21CTO (21CTO.com) offers developers community, training, and services, making it your go‑to learning and service platform.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.