What is software architecture?

Software architecture is the organizational structure of a system, defining how its components (modules, services, databases, interfaces, etc.) are distributed, interconnected, and interact with each other. It captures high‑level decisions that influence:

  • Quality (performance, security, maintainability, scalability…)
  • Distribution of responsibilities among teams and parts of the code
  • Ease of evolution of the system over time

In short, architecture provides the “skeleton” on which detailed code is built.

Main characteristics of software architecture

Characteristic What it means Why it matters
Modularity Divides the system into well‑defined components or modules with clear interfaces. Facilitates understanding, reuse, and maintenance isolated from other parts of the code.
Scalability Allows the system to grow in load (more users, more data) without degrading performance. Keeps the application responsive as demand increases.
Performance Defines how the system meets response‑time requirements and resource usage (CPU, memory, I/O). Users expect fast responses; bottlenecks can hurt the experience.
Security Incorporates authentication, authorization, encryption, auditing, and protection against threats. Prevents data leaks and attacks that could compromise system integrity.
Maintainability Structures the code so that changes, fixes, and evolutions are simple and low‑risk. Reduces support costs and speeds delivery of new features.
Extensibility Enables adding new features or swapping components without large refactorings. Keeps the pace of innovation throughout the product’s life.
Reliability / Resilience Guarantees the system continues operating correctly even with partial failures. Minimizes interruptions and improves user trust.
Testability Makes it easy to create automated tests (unit, integration, acceptance). Detects defects early and ensures continuous quality.
Portability Allows the software to run in different environments (OS, hardware, cloud). Expands product reach and reduces technological lock‑in.
Interoperability Defines how the system communicates with other systems or services (APIs, standards). Enables integrations and broader ecosystems.

How to use these characteristics in practice

  1. Set priorities – Not every project needs high scalability or extreme security; choose the traits that meet business requirements.
  2. Document architectural decisions – Record why each characteristic was adopted, the trade‑offs considered, and who will own it.
  3. Continuously validate – Use metrics (response time, test coverage, failure rate) to monitor whether the architecture meets its goals.

Other suggested steps

  • Map non‑functional requirements of your project and align each one with the characteristics above.
  • Create high‑level diagrams (e.g., component or deployment diagrams) that highlight modularity, communication, and security hotspots.
  • Establish a periodic evaluation plan to review whether the architecture still satisfies needs as the system evolves.

Common Types of Software Architecture

Quick Summary

  • Monolithic – Simplicity, lower operational overhead.
  • Client‑Server – Classic web model.
  • Layered – Clear responsibility separation.
  • Hexagonal / Clean – Domain isolation.
  • MVC / MVVM – UI layer organization.
  • Microservices – Autonomy and scalability.
  • Serverless – On‑demand execution, no fixed servers.
  • SOA – Heavy corporate integration.
  • Event‑Driven – Decoupling and async processing.
  • CQRS – Optimized read vs. write paths.
  • P2P – Decentralized networks.
  • Component‑Based – Reuse of UI/logic blocks.
Architecture Type Brief Description Typical Situations Where Chosen
Monolithic All code runs in a single process/artifact. Components are tightly coupled, but internal communication is simple (function calls). Small or initial projects where simplicity of deployment outweighs scalability needs.
Layered (Layered) Organized into logical layers (e.g., presentation → business → persistence). Each layer only knows the one directly below it. Enterprise systems that need clear separation of concerns and easy layer replacement (e.g., swapping a database).
Client‑Server Division between a server providing resources and a client consuming them over a network. Traditional web applications or desktop apps that rely on a centralized backend.
Microservices Set of small, independent, deployable services communicating via APIs (REST, gRPC, messages). Each service owns its own domain and often its own database. Large systems requiring high scalability, team autonomy, and fault tolerance.
Service‑Oriented Architecture (SOA) Similar to microservices but focused on reusable corporate services, usually exposed via an ESB (Enterprise Service Bus) or SOAP messages. Organizations with heavy integration workloads and legacy systems needing interoperability.
Event‑Driven (Event‑Oriented) Components react to events published on a bus (e.g., Kafka, RabbitMQ). Can be pub/sub or CQRS. Systems needing high decoupling, asynchronous processing, and horizontal scalability.
Hexagonal (Ports & Adapters) Core application (domain) sits in the center, surrounded by “ports” that define interfaces and “adapters” that connect external infrastructure (DB, UI, APIs). When you want to isolate business logic from external tech, facilitating testing and swapping frameworks.
Clean Architecture Evolution of Hexagonal: concentric layers (Entities → Use Cases → Interface → Frameworks). Dependencies always point inward. Projects prioritizing framework‑independent business logic and rigorous testability.
MVC / MVVM / MVP UI separation patterns: Model (data), View (interface), Controller/Presenter/ViewModel (interaction logic). Applications with rich user interfaces (web, desktop, mobile) that need clear UI organization.
CQRS (Command Query Responsibility Segregation) Separates write operations (commands) from read operations (queries), allowing optimized data models for each. Systems with high read/write disparity needing differentiated performance.
Serverless Code (functions) executed on demand in managed platforms (AWS Lambda, Google Cloud Functions). No permanent servers to manage. Intermittent workloads, event‑driven APIs, or short‑duration processing pipelines.
Peer‑to‑Peer (P2P) Nodes act simultaneously as client and server, sharing resources directly. File‑sharing applications, decentralized networks, blockchain‑related solutions.
Component‑Based System composed of reusable, interchangeable components, each encapsulating UI and/or logic. Modern front‑ends (React, Angular, Vue) and systems valuing visual composition.

How to Choose the Right Architecture?

  1. Non‑functional requirements – Do you need scalability? Security? Low latency?
  2. Domain complexity – Rich domains often benefit from microservices or hexagonal.
  3. Team and culture – Microservices require mature DevOps; monoliths may be easier for small teams.
  4. Operational cost – Serverless can reduce expenses for variable loads but has execution‑time limits.
  5. Future evolution – Architectures favoring decoupling (hexagonal, event‑driven) ease later changes.

Choosing the right style involves balancing technical, business, and team factors. Evaluate each style against those factors and, if needed, combine them (e.g., microservices communicating via events).


MVC, Layered, or Hexagonal

MVC, layered, or hexagonal architecture are three different styles that help organize code and separate responsibilities when designing a system.

MVC (Model‑View‑Controller) splits the application into model (data and business logic), view (user interface), and controller (coordination between model and view), which is useful when there is a well‑defined graphical or web interface and you want to keep the UI decoupled from the logic.

Layered architecture organizes the software into hierarchical levels—such as presentation, application, domain, and infrastructure—where each layer can only depend on the layers below it, facilitating maintenance and testability in more traditional or corporate projects.

Hexagonal (or ports‑and‑adapters) places the core business‑logic at the center and defines “ports” that expose functionality, while “adapters” connect this core to external interfaces (databases, APIs, UI), promoting high technology independence and allowing external components to be swapped without impacting the domain.

When choosing among them, consider factors such as UI complexity, the need to isolate business logic, the frequency of changes in external dependencies, and the team’s culture.

Below are real‑world examples of these architectures applied by companies in their systems:

Architecture Real‑world Context (company / product) Why the choice makes sense? Critical points to watch
MVC E‑commerce SaaS startup that launched an online store platform (Shopify‑lite). Works well when business logic isn’t extremely complex. Does not solve deep domain coupling; may need migration to a more robust architecture (e.g., Hexagonal) as the domain grows.
Layered Core banking system of a regional bank that processes accounts, transactions, and regulatory reports. Provides clear separation of concerns, useful for audit and regulation. Can generate implicit coupling between adjacent layers (e.g., Application layer knowing Persistence details). Less flexible for swapping infrastructure compared to port‑adapter styles.
Hexagonal (Ports & Adapters) Payments platform similar to Stripe, a fintech that must quickly integrate many providers, banks, and channels (mobile, web, POS). Requires disciplined isolation of core business logic; enables plugging in many external adapters. May feel over‑engineered for very small projects; risk of leaking external dependencies into the core if discipline lapses.

Practical Decision‑Making Steps

  1. Map non‑functional requirements
    • UI‑intensive / need fast rendering → MVC is usually sufficient.
    • Regulation, audit, clear responsibility separation → Layered.
    • Multiple external integrations, frequent adapter changes → Hexagonal.
  2. Assess domain complexity
    • Simple domain (CRUD for articles, tasks) → MVC or Layered.
    • Rich domain (complex business rules, payment flows, interest calculations) → Hexagonal or Clean Architecture.
  3. Consider team maturity
    • New or small teams may gain productivity using established MVC frameworks.
    • Experienced, multidisciplinary teams (backend, DevOps, QA) can leverage the separation of ports/adapters.
  4. Plan evolution
    • If there’s a likelihood of changing the persistence layer (e.g., SQL → NoSQL) or adding new channels (mobile, IoT), Hexagonal reduces change cost.
    • For primarily internal applications with a fixed database technology, Layered may be more straightforward.

Quick Decision Matrix

Typical Situation Recommended Architecture Main Reason
Web app with rich UI, little domain logic MVC Ready‑made UI separation, native framework support
Stable corporate system needing strong audit Layered Well‑defined layers facilitate governance and maintenance
Product that must integrate dozens of external services and frequently change adapters Hexagonal Independent core, plug‑and‑play adapters, isolated testing

Use these as starting points; the final choice should always reflect your specific requirements, team culture, and long‑term strategy.

Use of generative AI to assist in the construction of text and images.