Architecture patterns for systems analysts

Train for your next tech interview
1,500+ real interview questions across engineering, product, design, and data — with worked solutions.
Join the waitlist

Why interviewers ask about patterns

Architecture patterns are the lingua franca of system design rounds. When an interviewer at Stripe or Uber sketches a payments service and asks "where does the domain logic live", they expect you to map components to a known pattern within thirty seconds — layered, hexagonal, clean, or CQRS — and explain trade-offs without flipping through a textbook.

Systems analyst loops skew the question slightly differently than developer loops. You will rarely be asked to implement the pattern; you will be asked to choose between two of them given a one-paragraph business context, then defend the choice when the interviewer changes a constraint mid-conversation. There are only six or seven patterns that come up consistently, and they all map to the same problem — how do we keep business rules separate from the framework that hosts them?

Load-bearing trick: name the pattern, name the trade-off, name the failure mode you have personally seen. Three sentences. That is the structure interviewers grade on.

Layered (n-tier)

The oldest pattern in the deck, and still the default for most CRUD systems. Code is organized into horizontal layers, each layer only talking to the one directly beneath it. A typical four-layer stack looks like this:

Presentation (UI, REST controllers)
       ↓
Application (use cases, orchestration)
       ↓
Data Access (repositories, ORM mappers)
       ↓
Database (Postgres, MySQL)

Pros. Onboarding is trivial — any engineer who has shipped a Spring Boot or Django app already speaks the dialect. Layer boundaries map onto package structure, which means code review can mechanically flag leaks. Separation of concerns is "good enough" for products under roughly 100k lines of code.

Cons. The application layer turns into a junk drawer once the domain grows. Teams hit what Martin Fowler calls the anaemic domain model — entities become data bags, all logic drifts upward into services, and unit testing requires spinning up half the database.

Layered is still the right answer for an MVP, an internal admin tool, or any system where the domain rules are thin.

MVC, MVP, MVVM

Model-View-Controller is technically a UI pattern, not an application architecture, but interviewers conflate the two and you should be ready. The trio:

  • Model — domain state and rules.
  • View — how state is rendered to the user.
  • Controller — the mediator that translates input events into model updates.

Variants exist for nearly every UI framework. MVP swaps the controller for a presenter that holds view state explicitly; classic Android used this for a decade. MVVM adds two-way data binding and shows up in WPF, SwiftUI, and Vue. The substantive difference is who owns the formatted state the view consumes — controller, presenter, or view model — and the answer drives testability.

In a systems analyst interview, the right move is to flag MVC as a presentation concern that composes with a deeper application architecture like layered or hexagonal — it is not a substitute for one.

Hexagonal (ports and adapters)

Alistair Cockburn introduced hexagonal architecture in 2005 specifically to fight the layered-anaemic problem. The shape is inverted: the domain sits in the center, and everything external — UI, database, message broker, payment provider — is an adapter plugged into a port.

        ┌─── UI Adapter ───┐
        │                  │
Database Adapter ↔ DOMAIN ↔ External API Adapter
        │                  │
        └─── Test Adapter ─┘

Ports are interfaces defined by the domain ("I need a way to persist orders"). Adapters are concrete implementations of those interfaces (a Postgres repository, a DynamoDB repository, an in-memory fake for tests). The domain has no idea which adapter is plugged in.

Pros. The domain is isolated from infrastructure, which means you can run 80–95% of your test suite without a database. Swapping technologies is mechanical — moving from Postgres to Snowflake touches one adapter, not the whole codebase.

Cons. Boilerplate. Every new external dependency means an interface, an implementation, and wiring code. Overkill for a service that will live six months and call one database.

Sanity check: if you cannot delete the database and still compile the domain module, you are not actually doing hexagonal — you are doing layered with extra steps.

Clean architecture

Robert Martin's clean architecture is hexagonal with explicit, opinionated concentric layers and one famous rule. The diagram:

        Entities (domain rules)
            ↑
       Use cases (application rules)
            ↑
   Interface adapters (controllers, presenters, gateways)
            ↑
   Frameworks and drivers (DB, web, UI, devices)

The dependency rule. Source code dependencies can only point inward. Entities know nothing about use cases. Use cases know nothing about controllers. Controllers know nothing about the web framework. When data crosses a boundary going outward, it is converted to a form convenient for the outer layer.

Pros. Maintainability scales with codebase size. Testability is identical to hexagonal — pure domain tests run in milliseconds.

Cons. The boilerplate tax is real. A "create user" endpoint may involve a request DTO, a controller, a use case port, a use case implementation, an entity, a repository port, a repository adapter, and a response DTO — eight types where layered would use three. For a team of two shipping a v0, this is architecture astronautics.

Clean is the right answer when the domain is the product — fintech, healthcare, anything regulated. It is the wrong answer for a marketing site.

Train for your next tech interview
1,500+ real interview questions across engineering, product, design, and data — with worked solutions.
Join the waitlist

Microkernel and plugin systems

A microkernel keeps a minimal core and pushes everything else into plugins discovered at runtime. The canonical examples are easy to recognize:

Core (kernel) — extension API, lifecycle, plugin registry
Plugins — features loaded via the plugin API

VS Code, Eclipse, Salesforce, Figma, and every modern browser use this shape. The core is small, stable, and rarely changes; plugins are independently versioned and can be developed by third parties without touching the kernel.

Pros. Extensibility is the headline feature — you can ship a v1 with three plugins and a v2 with thirty without rewriting the core. Per-customer customization becomes feasible: enterprise tenants install plugin packages without forking the product.

Cons. The plugin API is a public contract from day one, and breaking it is expensive. Performance can suffer if every operation crosses a plugin boundary — VS Code's extension host runs in a separate process specifically to contain misbehaving plugins.

In an interview, microkernel is the right name when the prompt mentions "we want partners to extend the platform" or "different customers need different workflows." For "build a checkout service," reach for hexagonal instead.

CQRS at a glance

Command Query Responsibility Segregation splits the model in two: one shape optimized for writes, another for reads.

Commands → Write model → Event store / OLTP database
Queries  → Read model (often denormalized) → OLAP store / cache

The read model is usually denormalized — pre-joined, pre-aggregated, possibly materialized in a separate database. Writes go through commands that emit events; a projector consumes those events and updates the read store.

Pros. Read and write paths scale independently — you can run 20 read replicas and one write primary and tune each side for its actual query shape. Read models can be rebuilt from the event log when requirements change.

Cons. Eventual consistency is unavoidable — there is a window where a write has been accepted but the read model has not yet caught up. Total system complexity roughly doubles.

CQRS pairs naturally with event sourcing but does not require it. Plenty of CQRS systems use a regular OLTP database for the write model and a CDC pipeline to populate the read store.

Pattern comparison table

Pattern Best for Avoid when Testability Boilerplate
Layered CRUD apps, MVPs, admin tools Domain logic is the product Medium Low
MVC / MVVM UI composition Treating it as a backend pattern High (view layer) Low
Hexagonal Long-lived services, domain isolation Six-month throwaway High Medium
Clean Regulated domains, large codebases Two-person v0 Very high High
Microkernel Platforms with third-party extensions Single-tenant linear flows Medium High (API design)
CQRS Read-heavy workloads, separate scaling Strict consistency required High Very high

Common pitfalls

The most frequent failure in mock interviews is conflating layered with hexagonal. A candidate draws four boxes stacked vertically, labels them with hexagonal vocabulary, and calls it ports-and-adapters. The interviewer asks "where does the domain depend on the database" and the answer is "it imports the repository class directly." That is layered. The fix is to draw the domain as a circle in the middle and mark which arrows cross a port — if every arrow points into the domain, you have hexagonal; if any arrow points out toward infrastructure, you do not.

A second pitfall is defaulting to clean architecture for everything. Senior candidates do this because they read the book recently and it feels rigorous. The interviewer then asks how long the first endpoint will take to ship; the honest answer is two weeks for what should have been two days. The fix is to gate clean on domain complexity — if you cannot name three non-trivial business rules in the entity layer, layered is the right call.

The third pitfall is CQRS without justification. Candidates introduce a read model and an event store because the prompt mentioned "high read traffic," then fail to explain why a read replica with caching would not have solved the same problem at one tenth the operational cost. CQRS earns its complexity when read and write shapes diverge — different queries, different denormalizations, different SLAs — not when read volume is high.

A fourth pitfall is calling MVC an application architecture. MVC describes how UI state flows; it does not describe how the backend organizes domain logic. Saying "the service uses MVC" tells the interviewer you have not designed past a Rails scaffold. Pair a UI pattern with a backend pattern explicitly: "the web tier uses MVC controllers; the service tier is hexagonal with three ports."

Finally, candidates forget the dependency rule in clean architecture. They draw the layers correctly but then have the entity import a logging library, or the use case import the ORM. Both are violations. The fix is the compile-the-domain-without-the-database test: if the inner layers cannot build standalone, the rule is broken regardless of how the diagram looks.

If you want to drill systems analyst patterns like these every day, NAILDD ships 1,500+ interview questions across architecture, data modeling, and API design with exactly this trade-off framing.

FAQ

Is hexagonal the same as clean architecture?

They share the same dependency-inversion principle — the domain sits at the center and external code depends on it, not the other way around — but clean architecture adds explicit concentric layers (entities, use cases, interface adapters, frameworks) with a named dependency rule. Hexagonal is looser; it just demands ports and adapters around a domain core. For interview purposes, calling them siblings is accurate.

When does layered architecture actually break down?

The honest threshold is when the application service layer crosses roughly 3,000 lines and you start seeing methods named processOrderAndUpdateInventoryAndSendEmail. That is the anaemic domain model in flight. The other signal is unit test setup: when every "unit" test needs three mock repositories and a fake clock, the layers have leaked into each other and a hexagonal refactor will pay for itself within a quarter.

Should I use CQRS for a side project?

Almost certainly not. CQRS earns its complexity when the read and write paths diverge enough that a single model is actively harmful — different query shapes, different scaling needs, different consistency requirements. For a side project, a Postgres replica and a Redis cache cover 95% of cases at one fiftieth the operational cost.

How do microservices relate to these patterns?

Microservices are an organizational and deployment pattern, not an application architecture. Each microservice still needs to pick layered, hexagonal, or clean internally. A monolith and a microservice can both be hexagonal; the difference is the deployment unit, not the code organization.

What pattern should I default to for a system design interview?

For a long-lived backend service handling business logic, hexagonal is the safest default — high testability, well-known enough that the interviewer will not ask you to justify the name, composes well with event-driven, CQRS, and microservices. For a UI-heavy frontend, MVVM or a unidirectional flow like Flux. For an ETL job that runs once a day, layered is fine. Match the pattern to the lifespan and complexity of the system, not to the depth of your reading list.