A Layered Cargo Cult

#architecture #microservices #cargo-cult

Written by Anders Marzi Tornblad

Software architecture is the high-level design of a software system that defines its components, their interactions and the principles that guide their development. A good software architecture should be simple, consistent, modular and scalable. It should also support the functional and non-functional requirements of the system, such as performance, security and reliability.

However, not all software architectures are good. Some of them are based on copying or imitating other architectures without understanding their rationale or suitability for the problem at hand. This is what I call cargo-cult software architecture.

The Layered cargo cult

Cargo-cult software architecture is a term inspired by the cargo cults of some Pacific islands during the first half of the 20th century. These cults emerged when the islanders observed the arrival of airplanes with cargo from foreign countries. They believed that by building replicas of runways, control towers and airplanes with bamboo and coconuts, they could attract more cargo from the sky. Of course, this did not work.

Similarly, some software developers blindly follow popular or trendy architectures without questioning their purpose or applicability for their own projects. They add layers upon layers of abstraction and indirection to their code, hoping that this will make it more robust or flexible. However, this often has the opposite effect.

One of the most common examples of cargo-cult software architecture is layered architecture. Layered architecture is a way of organizing code into separate levels of abstraction that depend on each other in a hierarchical manner. For example, a typical web application may have a presentation layer (frontend), an application layer (controller), a business layer (service), a data access layer (repository) and a data source layer (database).

Layered architecture has some benefits when used properly. It can help to separate concerns, promote reusability and testability and facilitate changes in one layer without affecting others. However, it also has some drawbacks when used excessively or inappropriately.

However, layered architecture also has many drawbacks: it introduces artificial boundaries and dependencies between layers that may not reflect the actual domain model or use cases; it adds overhead and latency due to multiple calls across layers; it creates boilerplate code for mapping and transforming data between layers; it obscures the flow of control and data within the system; it hinders refactoring and evolution due to rigid layering rules; it encourages anemic domain models that lack behavior and logic; it violates the principle of least astonishment by hiding important details behind abstractions.

In conclusion, while layered software design can be an effective way to organize complex systems, blindly following established patterns can lead to cargo-cult behavior and overly complex, difficult-to-maintain systems. Instead, software developers should approach the design process with a critical eye, evaluating the trade-offs of different design patterns and adapting to the needs of their specific use case. By doing so, they can create systems that are easier to maintain and that deliver more value to their users.

In my opinion, most layered software contains way too many layers, and the downsides of having too many layers are:

These drawbacks lead to lower productivity and quality of software development. It makes development and bug fixing slow. Making small changes to data structures or logic often results in the "shotgun surgery" antipattern.

Shotgun surgery is an antipattern that occurs when a single change requires modifications in many places across the system due to high coupling between components. This makes the change tedious and error-prone as it increases the risk of introducing new bugs or breaking existing functionality.

So how can we avoid these problems? How can we design better software architectures that are not based on cargo-culting existing patterns without understanding their purpose or context? Here are some suggestions:

In conclusion, layered architecture is not inherently bad, but it can be misused or overused by developers who follow cargo-cult programming practices. We should be aware of the tradeoffs and pitfalls of this architectural style, and apply it judiciously and appropriately to our specific context and needs. We should also be open-minded and curious about alternative approaches that may offer better solutions to our problems. We should strive for simplicity, clarity, coherence, and elegance in our software architectures, as they are essential qualities for creating high-quality software systems.