Software architecture
What software architecture decides
Software architecture answers structural questions that are expensive to reverse later. It is less about which framework or language you pick and more about how the system is divided and how its parts depend on each other.
The core decisions usually cover:
- Decomposition — how the system is split into modules, services, or layers, and what each is responsible for.
- Communication — whether components call each other synchronously (HTTP, RPC) or asynchronously (message queues, events).
- Data ownership — which component owns which data, and how consistency is handled across boundaries.
- Dependencies — the allowed direction of dependencies between parts, to prevent tangled coupling.
- Cross-cutting concerns — authentication, logging, error handling, and observability applied consistently.
Good architecture aligns these choices with non-functional requirements: expected load, team size, deployment frequency, and how often the business logic is likely to change.
Common architectural styles compared
There is no universally best style. The right choice depends on team structure, scaling needs, and how much operational complexity the organisation can sustain. The three styles below cover most business applications.
| Style | Principle | Best suited to | Main trade-off |
|---|---|---|---|
| Monolith | The whole application is built and deployed as a single unit. | Small to mid-size teams, early-stage products, well-bounded domains. | Simple to deploy and debug, but can become hard to change as the codebase grows. |
| Microservices | The system is split into independently deployable services, each owning its domain and data. | Large organisations with multiple autonomous teams and uneven scaling needs. | Independent scaling and deployment, at the cost of network complexity, distributed data, and heavy operational tooling. |
| Hexagonal (Ports and Adapters) | Business logic sits at the centre; databases, UIs, and external services connect through interchangeable adapters. | Domains with complex, long-lived business rules that must outlast their infrastructure. | Strong testability and isolation, but more upfront abstraction and discipline. |
These styles are not mutually exclusive. A monolith can be organised internally along hexagonal lines, and a microservices estate can apply hexagonal principles inside each service.
Why architecture drives maintainability
Maintainability is largely an architectural property. When responsibilities are clearly separated and dependencies point in a controlled direction, a change in one area stays contained instead of rippling across the system.
Architecture supports maintainability through several recurring principles:
- Separation of concerns — each component has a single, well-defined responsibility.
- Loose coupling — components interact through stable interfaces, so internals can change without breaking callers.
- High cohesion — related logic lives together rather than being scattered.
- Explicit boundaries — clear contracts make it safe for different people, or teams, to work in parallel.
When these are neglected, systems accumulate technical debt: small changes require touching many files, testing becomes fragile, and onboarding new developers takes longer. Architecture is the lever that keeps the long-term cost of change predictable.
Questions fréquentes
Building a custom software project? We design bespoke software aligned with your roadmap.
See our custom software expertiseDéfinitions liées