This domain is lightly tested in the CPSA-F exam, but understanding real-world examples deepens your grasp of all other domains. Architecture is best learned by studying how others have solved real problems โ and by understanding why they made specific trade-offs.
9.1 Styles vs. Patterns vs. Design Patterns
These terms are often confused. Understanding the distinction helps you communicate precisely:
| Concept | Scope | Examples | Analogy |
|---|---|---|---|
| Architectural Style | High-level structural organization of the entire system. | Client-server, layered, event-driven, REST, pipe-and-filter | City planning |
| Architecture Pattern | A proven solution for a specific recurring problem at system level. | MVC, CQRS, Saga, Circuit Breaker, Strangler Fig | Building design |
| Design Pattern | A solution at the object/class level. Code-level design problems. | Strategy, Observer, Factory, Decorator, Singleton | Interior design |
9.2 Reference Architectures
Web Application (3-Tier)
The most common architecture for business applications. A presentation tier (browser/mobile), an application tier (business logic, stateless), and a data tier (database). The application tier is typically deployed as a single deployable unit (monolith) or a collection of services.
| Quality Focus | Architectural Tactic |
|---|---|
| Scalability | Stateless app tier โ horizontal scaling behind a load balancer |
| Availability | Multiple app instances, database replication, health checks |
| Security | HTTPS, authentication middleware, input validation, CORS |
| Performance | CDN for static assets, caching layer (Redis), connection pooling |
Event-Driven Architecture
Components communicate through events (facts about things that happened). Producers publish events to a broker (Kafka, RabbitMQ, AWS SNS/SQS); consumers subscribe and react. Strong decoupling, but adds complexity in debugging and consistency.
| Quality Focus | Architectural Tactic |
|---|---|
| Loose coupling | Producers don't know consumers; events are immutable facts |
| Scalability | Consumers scale independently based on throughput needs |
| Resilience | Messages persist in broker even if consumer is temporarily down |
| Consistency | Eventual consistency; requires careful event ordering and idempotency |
Batch Processing (ETL)
Scheduled jobs that extract data from sources, transform it, and load it into a destination. Uses pipes-and-filters pattern. Common in data warehousing, reporting, and data migration. Modern versions use tools like Apache Spark, AWS Glue, or dbt for SQL transformations.
Mobile + Backend for Frontend (BFF)
Instead of having mobile and web clients call the same generic API, each client type gets its own backend (BFF) tailored to its needs. The BFF aggregates, transforms, and optimizes data for its specific client. This prevents the "one API to rule them all" problem where the API becomes bloated trying to serve every client type.
9.3 Monolith vs. Microservices โ The Spectrum
This is one of the most debated topics in software architecture. The reality is that it's a spectrum, not a binary choice:
Case Study: E-Commerce Platform
Consider an e-commerce platform like a simplified Amazon. Here's how architecture decisions map to quality requirements:
Service Boundaries (Domain-based decomposition)
Key Architectural Decisions
| Decision | Rationale | Trade-off |
|---|---|---|
| Microservices over monolith | 5 teams of 6 devs each; independent deployment needed; different scaling needs per service | Operational complexity; need investment in CI/CD, monitoring, tracing |
| Event bus (Kafka) between services | Loose coupling; services can evolve independently; events provide audit trail | Eventual consistency; debugging is harder; event schema evolution |
| CQRS for Product Catalog | 10:1 read-to-write ratio; search requires different data model than catalog management | Two data stores to maintain; sync lag between write and read |
| Saga for Order + Payment + Inventory | No distributed transaction; each service owns its data | Compensating transactions needed on failure; complex failure modes |
Lessons Learned
- Start with a monolith โ Extract services only when you have clear domain boundaries and team boundaries
- Invest in observability early โ Distributed tracing (Jaeger/Zipkin), centralized logging (ELK), and metrics (Prometheus/Grafana) are prerequisites, not nice-to-haves
- Event schema evolution is hard โ Use a schema registry (Avro/Protobuf) from day one
- Test the failure modes โ What happens when Kafka is down? When a service is slow? Chaos engineering is not optional for microservices
Case Study: Legacy Modernization with Strangler Fig
A 15-year-old monolithic banking application needs modernization. Rewriting from scratch is too risky (the "big bang" approach has a high failure rate). Instead, use the Strangler Fig pattern:
- Put a proxy/facade in front of the monolith that routes all traffic
- Extract one capability at a time as a new service behind the proxy
- Route traffic gradually from legacy to new service (feature flags, canary releases)
- Repeat until the legacy monolith is empty (or contains only what doesn't justify migrating)
The Strangler Fig pattern is named after a tropical fig tree that grows around a host tree, eventually replacing it entirely. The key advantage: you're always in a working state โ there's no "construction period" where nothing works.
Summary
| Concept | Key Takeaway |
|---|---|
| Style vs. Pattern vs. Design Pattern | Style = system shape; Pattern = subsystem solution; Design Pattern = code-level solution |
| 3-Tier Web | Most common reference architecture; stateless app tier enables horizontal scaling |
| Event-Driven | Loose coupling via events; eventual consistency; great for integration |
| Monolith Spectrum | Start modular monolith โ extract services only when needed |
| Strangler Fig | Gradual migration from legacy โ always in a working state |
| Architecture decisions | Every decision is a trade-off โ document the rationale, not just the choice |