Software Engineering Practices
Adopt processes and patterns for building maintainable, scalable software.
Content
Architecture and Layering
Versions:
Watch & Learn
AI-discovered learning video
Sign in to watch the learning video for this topic.
Architecture and Layering — Building Software That's Easy to Change
"Good architecture is like a good recipe: it keeps the kitchen from exploding when you add more cooks." — probably a stressed CS50 TA
You've already learned how to capture what the user needs with Requirements and User Stories and how to iterate quickly with Prototyping and Feedback. You also explored Cybersecurity and Privacy Essentials to write safer code. Now we connect those dots: architecture and layering are the design decisions that make user stories feasible, prototypes evolve into products, and security controls actually stay in place as the system grows.
What is Architecture and Layering?
- Architecture: the high-level structure of a software system — components, their responsibilities, and how they interact.
- Layering: a specific architectural style that groups responsibilities into ordered layers (e.g., Presentation → Business Logic → Data Access).
Why it matters: good layering enforces separation of concerns, reduces accidental coupling, makes testing easier, and helps implement security controls at the right places.
Micro explanation
- Separation of concerns: keep user-interface code out of database logic.
- Loose coupling: change one layer (say, UI) without rewriting others (say, database queries).
Common Layered Architecture (and why you'll see it everywhere)
Typical layers in many CS50-style web apps or projects:
- Presentation / UI Layer — handles input and display (HTML/CSS/JS, React, templates).
- Application / Business Logic Layer — enforces rules, coordinates actions, implements user stories.
- Domain / Model Layer — core entities and validations (e.g., User, Post, Transaction).
- Data Access / Persistence Layer — talks to databases or APIs, abstracts storage details.
- Infrastructure / External Services — email, payment gateways, cloud storage.
Think of it like a restaurant: the UI is the menu and server, business logic is the chef following recipes (user stories), the database is the pantry, and infrastructure is the delivery service.
Quick analogy: Layers = Lenses
Each layer gives a different “lens” on the system. When you debug, you choose the lens: UI, business rules, or database.
How this builds on Requirements and Prototyping
- Requirements/User Stories tell you what the system must do — e.g., As a user, I want to reset my password.
- Architecture tells you where that functionality lives (UI shows reset form, business logic verifies token, data layer updates password).
- Prototyping helps validate assumptions for each layer quickly: will users accept the reset flow? Will the DB handle concurrent requests?
Design iteratively: prototype the UI and a mocked backend, then replace mocks with real layered components as feedback stabilizes.
Practical Patterns: MVC, Layered, Hexagonal (Ports & Adapters)
- MVC (Model-View-Controller): common for web apps. Models = data, Views = presentation, Controllers = handle input and coordinate.
- Layered Architecture: explicit layers with strict dependencies from top to bottom.
- Hexagonal (Ports & Adapters): isolates the domain from infrastructure via well-defined ports — makes swapping a DB or web framework easier.
When to pick what:
- Small CS50 projects: MVC or simple layered model is fast and effective.
- Complex, long-lived apps: consider hexagonal if you expect heavy changes to external services.
Example: Simple File Structure (Flask + JS)
project/
├─ frontend/ # Presentation (React or static HTML + JS)
├─ backend/
│ ├─ controllers/ # Controllers / API endpoints
│ ├─ services/ # Business logic
│ ├─ models/ # Domain objects / ORM models
│ └─ repositories/ # Data access
└─ infra/ # Integrations: email, storage
This structure keeps the what separated from the how.
Security and Privacy: Layered Defense (builds on Cybersecurity Essentials)
Architecture isn't neutral for security. Use defense-in-depth across layers:
- Presentation: input validation, CSRF tokens, proper headers (CSP).
- Business Logic: authorization checks, rate limiting, session handling.
- Data Access: parameterized queries, least privilege DB accounts, encryption at rest.
- Infrastructure: secure secrets management, firewalling, logging and monitoring.
A common failure: doing authentication only in the UI and trusting client data. Put checks in the server-side business layer too. Remember what you learned earlier: safer code is layered code.
Testing and Maintainability
Layering helps testing:
- Unit test the business logic in isolation (mock the data layer).
- Integration test the data-access with a real or test DB.
- End-to-end test the full stack occasionally to validate real flows.
Benefits:
- Easier to reason about failures (narrow down to a layer).
- Incremental refactoring with lower risk.
Trade-offs and Anti-patterns
- Too many layers = bureaucratic slime: slower development and more indirection.
- Tight coupling across layers (e.g., UI directly building SQL): breaks separation.
- Premature abstraction: don't over-engineer before requirements stabilize (use prototyping feedback to guide complexity).
Ask: does the added layer solve an actual problem (change, testing, security), or are we just being fancy?
Quick Checklist for Designing a Layered System
- Map each user story to the layers it touches.
- Define clear responsibilities and interfaces between layers.
- Keep layers loosely coupled and highly cohesive.
- Plan tests per layer (unit, integration, e2e).
- Add security controls at appropriate layers (defense-in-depth).
- Re-evaluate after prototyping and user feedback.
Key Takeaways
- Architecture and layering turn user stories into sustainable systems. They help your prototypes scale without collapsing under new requirements.
- Separation of concerns = easier testing, safer code, and less hair-pulling when things change.
- Security is layered. Apply defensive controls across presentation, logic, and data layers — not just where it's convenient.
"If your app was a house, layering is the foundation, wiring, locks, and plumbing all planned so you don’t discover leaks during a party." — marry that image to your next CS50 project.
Final small assignment (CS50-flavored)
- Pick a user story from your project (e.g., 'create post with image').
- Draw the layers it will touch and list one responsibility for each layer.
- Identify one security control you will add per layer.
- Prototype the UI and mock the service layer; iterate with feedback.
Do this and next time you touch the codebase, you'll thank your past self.
Comments (0)
Please sign in to leave a comment.
No comments yet. Be the first to comment!