The Cost of Architectural Symmetry
Why different responsibilities deserve different amounts of structure. There is something reassuring about opening a codebase and recognizing its structure. The controllers are where we expect them to be. The services follow a familiar convention. Before we understand the details, we already have a sense of how to move through the system. I think that predictability explains a lot of our…
The architectural structure of software can bring a sense of predictability and consistency, but it also adds complexity when following operations across multiple components. Each layer, like a controller, service, and repository, contributes to the overall system's architecture, but the question arises whether all layers are necessary for every operation.
A simple read operation, for example, may pass through a controller, a service interface, a service implementation, a repository interface, and a repository, with the service merely forwarding the customer ID and returning the result. This unnecessary layering can hinder understanding of the system, requiring engineers to carry the entire chain of dependencies in their heads.
The attachment to symmetry in architecture often leads to the creation of additional components, even when they don't provide a specific responsibility. This is similar to how different rooms in a house have unique structures despite shared construction standards, based on their different purposes. Software should allow for variation in architecture according to the specific requirements of operations, rather than forcing them into a uniform structure.
Organizations often impose a template with predefined layers on applications, irrespective of their actual needs. This can lead to engineering decisions that prioritize fitting the problem into a predetermined design rather than making design choices based on the specific constraints and physics of the system. Templates can still provide useful knowledge such as common approaches to logging, configuration, deployment, and observability, but they should not dictate the architecture for every application.
The decision to include certain components in a template should be based on whether they provide actual engineering benefits, not just to satisfy a perceived future need. Over-engineering, in other words, can result in unnecessary components that add complexity without necessarily improving the system. It's important to distinguish between changes that are expected and those that are merely imagined, and to invest in flexibility only when there's a clear need.
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.