← Back to Software Architecture

6 Software Architecture Patterns

Six software architecture patterns for layering, service boundaries, and data flow.

Software ArchitectureArchitectureDesign Patterns

Architectural patterns are not medals for sophistication. They are recurring structural responses to recurring forces such as growth, change rate, deployment risk, or domain complexity. The right pattern is the one whose tradeoffs match the problem you really have.

  1. Layered architecture. A classic structure that separates presentation, application, domain, and data concerns. It is easy to understand, but deep layers can also hide performance and ownership issues.

  2. Hexagonal architecture. Places the domain in the centre and treats databases, queues, and web frameworks as adapters. This keeps business rules less coupled to infrastructure choices.

  3. Event-driven architecture. Systems communicate by publishing and reacting to events. It scales integration well, but it requires discipline around schema evolution, ordering, and observability.

  4. Microservices. Useful when teams need independent deployment and clear bounded ownership, but expensive when service boundaries are weak or operational maturity is low.

  5. CQRS. Separates write models from read models so each side can be optimised differently. Powerful when query and command needs diverge sharply, but unnecessary complexity in many systems.

  6. Pipes and filters. Represents processing as stages connected by a data flow. It works well for compilers, ETL pipelines, and streaming transformations where each step is independently understandable.

Patterns help when they remove friction from the dominant change path. If your architecture constantly fights the way the business evolves, the pattern is not serving the system no matter how respectable it sounds on a diagram.

Choosing among patterns

Pattern choice should follow the dominant source of change. If most complexity lives in business rules, hexagonal or layered separation can help. If independent teams and release velocity are the pressure point, microservices may be justified. If the main workload is streaming transformation, pipes and filters can be a better fit than request-response structure.

Teams also need to resist accidental hybrid messes. Many troubled systems are not "using several patterns" so much as carrying several incomplete ones at once. A pattern is helpful when it creates clear ownership and predictable flow. It is harmful when it only adds ceremony and more boxes to draw.

A practical warning

Teams often copy a pattern name from a conference talk without copying the discipline that makes it work. A hexagonal system without clear ports, or microservices without platform tooling, quickly becomes harder than the simpler design it replaced. Pattern literacy should make you more selective, not more eager to add structure.