upgrade
upgrade

🖥️Programming Techniques III

Software Architecture Patterns

Study smarter with Fiveable

Get study guides, practice questions, and cheatsheets for all your subjects. Join 500,000+ students with a 96% pass rate.

Get Started

Why This Matters

When you're building software beyond simple scripts, the way you organize your code determines whether your system thrives or collapses under its own weight. Architecture patterns aren't just theoretical constructs—they're battle-tested solutions to problems like how do I add features without breaking everything?, how do I scale when users multiply?, and how do I let multiple teams work without stepping on each other? You're being tested on your ability to recognize which pattern solves which problem and why.

These patterns demonstrate core principles you'll encounter throughout your career: separation of concerns, loose coupling, high cohesion, and scalability strategies. The exam won't just ask you to define MVC or list the layers in N-tier architecture. You'll need to analyze scenarios and recommend appropriate patterns, explain tradeoffs, and understand when one pattern outperforms another. Don't just memorize names—know what problem each pattern solves and what principles it embodies.


Structural Separation Patterns

These patterns solve the fundamental problem of organizing code into logical units. The core mechanism is dividing responsibilities so that changes in one area don't cascade throughout the system.

Layered (N-tier) Architecture

  • Horizontal separation into distinct layers—typically presentation, business logic, and data access, each with a single responsibility
  • Dependency flows downward only—upper layers can call lower layers, but lower layers never reference upper ones, enforcing clean boundaries
  • Independent layer modification—you can swap out a database or redesign a UI without rewriting business logic, enabling incremental upgrades

Component-Based Architecture

  • Encapsulated, reusable units of functionality—each component exposes a defined interface while hiding its internal implementation
  • Independent lifecycle management—components can be developed, tested, versioned, and deployed separately from the main application
  • Plug-and-play integration—components can be replaced or upgraded without system-wide changes, reducing maintenance risk

Model-View-Controller (MVC)

  • Three-way separation of concerns—Model handles data/state, View renders UI, Controller processes user input and orchestrates responses
  • Parallel development enabled—frontend developers work on Views while backend developers modify Models without merge conflicts
  • Testability through isolation—business logic in Controllers can be unit tested without rendering actual UI components

Compare: Layered Architecture vs. MVC—both enforce separation of concerns, but Layered organizes by technical function (data, logic, presentation) while MVC organizes by role in user interaction (what you see, what you do, what changes). If an FRQ asks about web application structure, MVC is usually your answer; for enterprise systems with multiple interfaces, think Layered.


Communication Patterns

These patterns define how components talk to each other. The key distinction is whether communication is synchronous (request-response) or asynchronous (fire-and-forget).

Client-Server Architecture

  • Clear role division—clients initiate requests, servers respond with data or services, creating a predictable interaction model
  • Centralized resource management—servers maintain authoritative data and enforce business rules, ensuring consistency across all clients
  • Protocol flexibility—supports HTTP, WebSocket, gRPC, and custom protocols, allowing diverse client types (web, mobile, IoT) to connect

Publish-Subscribe Pattern

  • Complete decoupling of producers and consumers—publishers emit events without knowing who (if anyone) is listening
  • Dynamic subscription management—subscribers can join or leave at runtime without modifying publisher code or causing failures
  • Fan-out capability—a single published message can reach multiple subscribers simultaneously, enabling broadcast communication

Event-Driven Architecture

  • Reactive system design—components respond to events as they occur rather than polling for changes, reducing latency
  • Asynchronous processing—event producers don't wait for consumers, allowing the system to handle load spikes gracefully
  • Temporal decoupling—events can be queued and processed later, making the system resilient to temporary component failures

Compare: Publish-Subscribe vs. Event-Driven—Pub-Sub is a messaging pattern (how messages flow), while Event-Driven is an architectural style (how the system behaves). Event-Driven architectures often use Pub-Sub as their communication mechanism. Think of Pub-Sub as a tool within the Event-Driven toolbox.


Service-Oriented Patterns

These patterns structure applications as collections of services rather than monolithic codebases. The driving principle is that independent services can evolve, scale, and fail independently.

Service-Oriented Architecture (SOA)

  • Loosely coupled services communicating over a network—services expose standardized interfaces (often SOAP/XML) regardless of internal implementation
  • Enterprise-scale interoperability—different departments can build services in different languages that still work together seamlessly
  • Service reusability across applications—a payment processing service built once can serve multiple applications, reducing duplication

Microservices Architecture

  • Small, single-purpose services with independent deployment—each service owns its data and can be deployed without coordinating with other teams
  • Technology diversity permitted—one service can use Python and PostgreSQL while another uses Go and MongoDB, optimizing for each problem
  • Granular scaling—scale only the services under load rather than the entire application, improving resource efficiency

Compare: SOA vs. Microservices—both decompose applications into services, but SOA typically involves larger services sharing an Enterprise Service Bus (ESB) for communication, while Microservices favor smaller services with direct API calls. Microservices emerged partly as a reaction to SOA's complexity. FRQs may ask you to identify which suits a startup (Microservices) versus a legacy enterprise integration (SOA).


Data Flow Patterns

These patterns focus on how data moves through a system. The core idea is creating predictable, often unidirectional paths for data transformation.

Pipe and Filter Architecture

  • Linear data transformation through connected stages—each filter performs one operation, passing output to the next filter via pipes
  • Filter composability and reuse—filters can be rearranged, added, or removed to create new processing pipelines without code changes
  • Parallel processing potential—independent filters can run concurrently on different data chunks, improving throughput

Repository Pattern

  • Abstracted data access through a unified interface—business logic calls repository methods like findById() without knowing if data comes from SQL, NoSQL, or an API
  • Centralized query logic—complex data retrieval is encapsulated in the repository, keeping business logic clean and focused
  • Testability via mock repositories—unit tests can substitute fake repositories that return predictable data without hitting real databases

Compare: Pipe and Filter vs. Repository—these solve different problems entirely. Pipe and Filter handles data transformation workflows (think Unix commands piped together), while Repository handles data persistence abstraction. Both promote separation of concerns but at different architectural levels.


Quick Reference Table

ConceptBest Examples
Separation of ConcernsLayered Architecture, MVC, Component-Based
Synchronous CommunicationClient-Server
Asynchronous CommunicationEvent-Driven, Publish-Subscribe
Service DecompositionSOA, Microservices
Data AbstractionRepository Pattern
Data TransformationPipe and Filter
Independent DeploymentMicroservices, Component-Based
Loose CouplingEvent-Driven, Publish-Subscribe, SOA

Self-Check Questions

  1. Which two patterns both enable parallel development by isolating components, but differ in how they define those components—one by technical layer, one by interaction role?

  2. A system needs to process real-time stock trades where multiple downstream services (logging, analytics, alerting) must react to each trade. Which pattern best fits, and why would Client-Server be insufficient?

  3. Compare and contrast SOA and Microservices: what shared principle do they embody, and what key differences would influence your choice for a new greenfield project versus integrating legacy enterprise systems?

  4. You're designing a data processing pipeline that ingests CSV files, validates records, transforms formats, and outputs to a database. Which pattern would you apply, and how does it promote reusability?

  5. An FRQ asks you to refactor a monolithic application where UI code directly queries the database. Which two patterns would you combine to introduce proper separation, and what specific problem does each solve?