4.5.5 · D5Software Engineering
Question bank — Software architecture — layered, MVC, event-driven, microservices, serverless
Picture the three shapes first
Before you answer traps, burn these three pictures into your head. Almost every trap below is really about which of these shapes you are looking at.

The one formula worth deriving: why brokers scale
The parent note claims direct calls cost "" and a broker costs "". Those symbols are earned below — nothing before it is defined.

True or false — justify
Layered architecture makes a system scalable.
False. Layers organise code for maintainability, but the whole stack usually deploys as one process; to scale you replicate the entire monolith, not a single layer. See Scalability — Horizontal vs Vertical.
In closed layered architecture the Presentation layer may call the Data layer directly if it needs speed.
False. As defined above, closed means no skipping — Presentation may only call the layer directly below it. Skipping re-couples the top to the bottom and destroys the isolation the layers exist to provide.
In MVC the View is allowed to contain business rules to save a round-trip.
False. The View must be "dumb" — it only renders the Model. Rules in the View can't be reused by other Views (a JSON API, a chart) and can't be unit-tested without a screen. See Design Patterns — MVC, Observer.
Event-driven architecture removes coupling entirely.
False. It removes spatial (who-calls-whom) coupling but introduces temporal coupling — ordering, duplicates, and eventual consistency between producer and consumer.
Microservices are always more scalable than a monolith.
False. They enable independent scaling of a hot service, but add network latency and ops cost. A well-structured monolith on bigger hardware often scales further per rupee for a small team.
Serverless means there are no servers.
False. Servers still run your code; you just don't manage them. The provider handles provisioning — see FaaS (Function-as-a-Service) — but cold starts, time caps and statelessness are real. (FaaS = you upload a single function; the cloud runs one copy per incoming event and bills only for that run.)
Lowering coupling and raising cohesion are two names for the same goal.
False. They are distinct axes — Coupling and Cohesion. Coupling is between modules (want low); cohesion is within a module (want high). You can have low-coupling, low-cohesion sludge.
An event broker with producers and consumers needs connections.
False. That is the direct-call cost derived above. The broker makes each side connect only to itself, giving — the structural win of brokers.
Adopting microservices is a purely technical decision.
False. By Conway's Law your architecture mirrors your org chart, so service boundaries and team boundaries are entangled — it's an organisational decision too.
Serverless is cheaper than a reserved server in every case.
False. Only when invocations are small or bursty. For huge, steady traffic the per-request overhead makes a reserved server cheaper.
Spot the error
"We split the app into 4 clean layers, so now each team can deploy independently."
Error: layers are a code split inside one deployable unit (the left shape in the figure ships as one box). Independent deployment needs separate deploy units (microservices), not horizontal layers.
"Our Controller validates input, checks inventory, charges the card, and renders HTML."
Error: that's a fat controller. Business logic (inventory, payment) belongs in the Model/Service; the Controller should be a thin router — see Design Patterns — MVC, Observer.
"We moved to microservices, and to keep data consistent all services share one central database."
Error: a shared database re-couples the services — a schema change breaks everyone. Each microservice must own its own data store (the per-service drum in the figure).
"Event-driven means we get a clean stack trace across all services when something fails."
Error: there is no single stack trace across an async broker. Debugging needs correlation IDs and distributed tracing instead.
"Serverless functions can hold a user's session in a local variable between requests."
Error: functions are stateless and can vanish or scale to fresh instances between calls. Session state must live in external storage (cache/DB).
"We're a 3-person team, so we started with 20 microservices to be future-proof."
Error: "microservices first" adds network, distributed-transaction and ops burden a tiny team can't afford. Start with a modular monolith; split only when a boundary truly needs it.
"The Observer pattern and event-driven architecture are unrelated ideas."
Error: they share the same core — publishers notifying subscribers without knowing them. Event-driven architecture is essentially Observer scaled across a network via a broker.
Why questions
Why do dependencies in layered architecture point downward only?
Because concerns change at different rates (UI often, DB rarely). One-way downward dependencies mean a fast-changing layer can be rewritten without touching the stable layers below.
Why does an event producer not know its consumers?
So you can add a new reaction (analytics, email) by adding a consumer, with zero change to the producer — the source of event-driven's extensibility, and the wiring shown above.
Why draw microservice boundaries around business capabilities, not technical layers?
A capability (Orders, Payments) is what changes and scales together and what a team owns. Splitting by layer would make every feature cross all services.
Why does serverless bill per invocation × duration instead of per hour?
Because most servers sit idle yet cost money 24/7. Pay-per-execution drives idle cost toward zero, which is the whole economic point.
Why is every architectural boundary also a cost, not just a benefit?
Each boundary needs glue code, indirection, and often a network hop. Architecture is a trade-off between lower coupling and this added overhead — more boundaries is not automatically better.
Why can MVC's Model be reused across a web page, a chart, and a JSON API?
Because the Model holds data and rules but knows nothing about any screen, so many independent Views can render the same single source of truth.
Edge cases
Layered: a request must pass through Presentation → Service → Domain → Data and back for every call. What's the hidden cost of stacking many layers?
Each layer adds a mapping/indirection hop, so a deep stack pays a per-call performance and boilerplate penalty — you copy data object-to-object at every boundary for no business gain. Depth buys isolation but not free.
Layered: the Data layer needs a value the Presentation layer holds, so a developer makes Data call upward. Why is this a defect?
It creates a cyclic dependency (down and up), which breaks the strict downward rule, makes layers un-testable in isolation, and re-tangles exactly what layering exists to separate. Pass the value downward as a parameter instead.
What happens to event ordering if two consumers process the same event at different speeds?
Their views of the world drift temporarily — this is eventual consistency. The system must tolerate reads that are briefly stale, or enforce ordering via the broker.
A serverless function hasn't been called in an hour, then a request arrives. What's the catch?
A cold start — the platform must spin up a fresh instance, adding latency. Scaling from zero is the trade-off for zero idle cost.
Your event broker delivers the same "OrderPlaced" event twice. What must consumers do?
Be idempotent — processing the duplicate must not double-charge or double-ship. At-least-once delivery makes duplicates a normal case, not a bug.
A long-running batch job takes 30 minutes. Good fit for serverless?
No. FaaS enforces execution time caps (often minutes) and is stateless, so long, stateful jobs are a poor fit; a container or reserved server suits better.
A monolith crashes. A microservice in one capability crashes. Compare the blast radius.
Monolith failure is all-or-nothing (one process down = app down). A single microservice failure is isolated, if the rest degrade gracefully instead of hard-depending on it.
Zero consumers are subscribed when a producer emits an event. What happens?
With a durable broker the event waits in the queue until a consumer appears; with pure fire-and-forget it's simply lost — a degenerate case you must design for.
Recall One-line summary of the traps
Organisation ≠ deployment; decoupling ≠ simplicity; big-company ≠ best-practice; "serverless" ≠ no-servers. The trap:::Confusing a code-level split (layers, MVC) with a deployment-level split (microservices, serverless).