Architectural Patterns: Catalogs, Styles, and Case Studies
Prerequisite Knowledge
This lecture builds on the following concepts from earlier lectures. If any feel unfamiliar, review the linked notes before proceeding.
Previously Covered in This Subject
- The three architecture structures — module, component-and-connector, and allocation — covered in Lecture 2
- Patterns as problem–context–solution triples — covered in Lecture 9
- The layered pattern — covered in Lecture 9
- Pipes and filters — covered in Lecture 9
10.1 Three Ways to Catalog Patterns
Hook: A library can shelve the same book under fiction, history, or travel — the book does not change, only the question the shelf answers. Architectural patterns work the same way: this session takes patterns you have already met and reshelves them into three families, so that picking up any pattern tells you immediately which kind of design question it answers.
10.1.1 Module, Component-and-Connector, and Allocation Families
There is more than one catalog of architectural patterns. An earlier session covered a catalog of distributed patterns — patterns for systems whose pieces run on different machines. This session organizes the same body of knowledge in a different way, by splitting every pattern into one of three families. Think of the families as three questions an architect is allowed to ask about any system:
- Module patterns — patterns that shape how code is divided into units. The layered pattern is the classic example here: you take a topic, divide it into parts called layers, and each layer uses the next layer below it. The question this family answers is "how do I split my code?"
- Component-and-connector patterns — patterns about interaction. You have blocks or subsystems that interact with one another, and the nature of the interaction differs from pattern to pattern. Broker, model-view-controller, pipes and filters, client-server, peer-to-peer, publisher-subscriber, shared data, and service-oriented architecture all live in this family. The question this family answers is "how should my pieces talk?"
- Allocation patterns — patterns about mapping software to the world it runs on. Multi-tier and MapReduce belong here; they talk about how software modules map onto hardware modules. The question this family answers is "where should my software sit?"
A useful way to remember the split: module patterns are about the shape of the code, component-and-connector patterns are about the conversation between pieces, and allocation patterns are about the address of each piece on real hardware. Reference books such as Gomaa's catalog group their patterns similarly — structure patterns, communication patterns, transaction patterns — which is the same instinct applied with different labels.
| Family | Question it answers | Unit being arranged | Examples |
|---|---|---|---|
| Module | How do I split my code? | Code units inside one system | Layered |
| Component-and-connector | How should my pieces talk? | Blocks/subsystems plus their links | Broker, MVC, pipes and filters, client-server, peer-to-peer, publisher-subscriber, shared data, SOA |
| Allocation | Where should my software sit? | Software units onto hardware units | Multi-tier, MapReduce |
The same pattern can be viewed through more than one lens — layered is listed under module, yet a layered system deployed across machines starts to look multi-tier — but knowing which family a pattern belongs to tells you what kind of question it answers before you read a single detail page. That is exactly why catalogs exist: they trade a little memorization for a large amount of orientation.
10.1.2 Recognizing Patterns and Their Benefits
A working architect needs the ability to "smell" these patterns when looking at an existing architecture. Nobody hands you a diagram with the patterns labeled; you see boxes and arrows, and the skill is to recognize which named pattern the structure is an instance of. These are the major patterns, and each has many variations. Think of the standard form as the vanilla pattern — the plain, textbook version; everything else is a variation of it, the way every ice-cream flavor is a variation of the plain scoop.
The practical skill works like this: you see a structure, you name its pattern, and the moment you have named it, you can state the benefits of using it. Naming is the key that unlocks the rest, because every pattern exists because it buys specific benefits — layered buys separation of concerns, broker buys location transparency, pipes and filters buy interchangeability. If you know briefly what each pattern is, you can always read the details later and understand what benefit the pattern was bought for. Without the name, the same details are just noise.
Worked mini-example of the recognition skill. You join a team and open the design document of an unfamiliar billing system. You notice: a UI block, a rules engine block, and a database block, where the UI talks only to the rules engine and the rules engine talks only to the database. You name it: layered (three layers, one-way usage). Instantly the benefits follow without reading further: each block can be upgraded separately as long as the interfaces hold, teams can own different blocks, and testing one block needs only a stand-in for its neighbor. Now suppose instead you had seen ten services all talking to one central lookup box before calling each other. Different name — broker — and so different benefits: services can move around freely because nobody addresses them directly, at the price of the central box becoming a busy point. Same recognition drill, different shelf.
Real-world: this recognition skill is exactly what you use when you join a team and must read an unfamiliar system quickly — spot the pattern first, then the details fall into place. It is also how experienced architects review proposals: they are not reading every line, they are asking "which pattern is this, and did the designers pay attention to the costs that come with it?"
Pitfalls:
- Treating the families as mutually exclusive boxes. A real system mixes patterns from all three families at once; the families classify questions, not whole systems.
- Confusing a variation with a violation. Seeing something that is not the vanilla form does not mean the pattern is absent — most deployed patterns are adapted, not textbook-pure.
- Memorizing pattern names without attaching one benefit and one cost to each. A name you cannot attach a benefit to will not survive the exam or a design review.
Three families — module (split the code), component-and-connector (let the pieces talk), allocation (place software on hardware). For every pattern in this lecture, practice the two-step reflex: name the vanilla pattern, then state the benefit it was bought for. The rest of the session walks that tour.
10.2 A Guided Tour of Component-and-Connector Patterns
This tour walks through the component-and-connector family quickly, one stop per pattern. The rule of the tour is the recognition skill from section 10.1: at every stop, learn the vanilla form of the pattern — its standard shape — and attach one benefit and one cost to it. Many variations of each pattern exist in practice; if you know briefly what each vanilla pattern is, you can always read the details later and understand what benefit it was bought for. Deeper treatments come later in this lecture (layered in 10.7, broker and proxy in 10.8, pipes and filters in 10.9, MVC in 10.11, SOA in 10.12).
10.2.1 Layered, Broker, and Model-View-Controller at a Glance
The layered pattern divides a system into parts where one layer uses the next layer down — presentation uses business, business uses data access. It is covered in depth in section 10.7.
A broker is an in-between component placed among two blocks. It helps a collection of blocks interact through one common point: services register with the broker, clients send requests to the broker, and the broker forwards or directs each request to the right service. Clients never need to know where a service actually lives — that property is called location transparency, and it is the main thing the broker is bought for. The price is that the common point can become a bottleneck under heavy load, and if it dies, everything behind it becomes unreachable. Sometimes you keep a backup for it despite the bottleneck, because funneling everything through one point buys you three things: no duplication of work (one place does the job instead of many), maintained consistency (everyone sees the same state), and proper allocation of resources (the broker can ration who gets served when). A broker serves many purposes at once.
Worked example — the real-estate broker. Think of finding a house in a new city. There are many landlords with flats to give, and many people looking for flats. Nobody could keep track of all the landlords personally, and no landlord could chase every tenant. A real-estate broker is the single point of contact between them: landlords register their flats once, tenants ask one person, and the matching happens at that meeting point. Trace what happens on both sides: a landlord lists a flat (registration), a tenant describes a need (request), the broker names the available match (forwarding). If the broker vanishes, everything goes away — both sides lose their meeting point, even though the landlords and tenants themselves are perfectly healthy. That is exactly the broker pattern's trade in software: huge convenience concentrated at one point, and one point of failure.
Model-view-controller (MVC) keeps one model, which maintains the data store, and offers many possible ways to look at that data. Views can be visualizations, graphics, tables, or simple lists — same numbers, different faces. A controller manages user interaction: the user interface connects to the controller, and the controller plays the role of an umpire who decides what needs to go to the model and what the views are allowed to see. Section 10.11 develops MVC fully.
10.2.2 Pipes and Filters, Client-Server, and Peer-to-Peer at a Glance
Pipes and filters looks like the piping network in a house or a factory. Blocks are connected by pipes. Each block is either a reservoir (it holds data) or a process unit (it transforms data). The pipes carry a common flow pattern. There can be slight variations between pipes, but if the pipes are absolutely uniform, then the modules between them become interchangeable — you can unplug one unit and plug in another freely, because every joint fits every unit. When you design a system so it can be rearranged like this, you have built a pipes-and-filters architecture. Section 10.9 goes deeper.
The client-server pattern applies when you decide that one powerful machine should provide a particular class of service. The client makes requests; the server answers them and never initiates them. The machine is capable of serving a very large number of users without being overburdened. Why put everything there? Reuse (every client shares the one implementation), common control (rules change in one place), and the freedom to give that machine very specialized features tuned to that one type of service. Typical examples are database servers and mail servers — the big ones.
Real-world: conventionally even storage sat on servers. Storage servers let people just save files centrally. Even today some companies — not IT companies, say a design firm — keep one local server, give engineers access to it, and tell them not to store anything anywhere else. A more useful way to work would be a shared file service such as Dropbox, OneDrive, or Google Drive, yet local servers still sit in offices, switched off at night, making their owners feel secure. The server is doing its job; the habit around it is what aged.
Peer-to-peer is everybody talking to everybody. Its advantage: there is no single common point whose failure kills the system — every node is a full participant, both asking and answering. WhatsApp feels like this, though in truth it does have central points that coordinate message delivery. Torrents are genuinely peer-to-peer: content opens out on the World Wide Web, gets distributed everywhere in pieces, and is collated back together from the pieces by whoever wants it. Reference texts treat peer-to-peer as a variation born from client-server where the client and server swap roles — every machine plays both.
10.2.3 Service-Oriented Architecture at a Glance
Service-oriented architecture (SOA) has been extremely popular over the last ten to twenty years and has been the subject of seminars for two decades. Many careers have been built on it. Its rise happened largely because legacy applications coexist with modern systems: a very large segment of SOA work consists of integrating legacy applications with current-day technologies, without rewriting the legacy side.
The move is this: you build a shell around an application. That shell becomes a service. The service offers functions to new applications through an agreed interface. Behind the service sits whatever application you like — the outside world does not care what is underneath, and the underneath can be replaced without anyone noticing as long as the shell's contract holds. People developing user interfaces or other applications interact only with the service, and the service interacts with whatever lives at the back. That arrangement is service-oriented architecture. Section 10.12 develops it fully.
Q: Is it possible to use multiple architecture patterns in one system? A: Yes, definitely. Not only is it possible — real systems are always like that. In fact, sometimes you use a pattern inside another pattern. A large service-oriented system may contain a broker inside it, and a layered module inside that. The families from section 10.1 classify questions, not whole systems, so one system naturally mixes answers: layered code inside a service, services meeting at a broker, the whole deployment spread across tiers.
Pitfalls:
- Judging a pattern by its worst property alone. Every stop on this tour has a cost — broker bottleneck, client-server dependence on one machine, peer-to-peer coordination overhead. Architects pick patterns whose costs they can live with, not patterns without costs.
- Assuming "peer-to-peer" means zero infrastructure. Popular systems that feel peer-to-peer often still have central coordination points; torrents are the cleaner example.
- Treating SOA as a product you install. It is an arrangement — a shell and a contract — around applications you already have.
Seven connector styles, seven one-line handles: layered = use only the layer below; broker = meet at one registered point; MVC = one model, many views, an umpire controller; pipes and filters = uniform joints make units interchangeable; client-server = one specialized provider, many requesters; peer-to-peer = everyone talks to everyone; SOA = a shell turns any application into a service. Name each, then recite its benefit and cost.
10.3 The Publisher-Subscriber Pattern
Hook: Every other pattern so far started with somebody asking for something. This one starts with the opposite: the service announces itself, and you receive news you never asked for at that moment. Why would anyone design a system where data arrives uninvited?
10.3.1 Request-Response versus Subscription
The publisher-subscriber pattern underlies even the model-view-controller arrangement described later in section 10.11, so keep it handy. In publisher-subscriber, there are people who require a service, but the service is not handed out on request. You cannot simply arrive with a user ID and password and pull the data. That model does not suit the situation, because you want to access the service not by requesting it but by being informed by it: "I've got something new to offer you. Take a look."
The cast has two roles. The publisher is the side that produces updates and keeps a subscriber list: an enrollment of everyone who said, in advance, "tell me when this kind of thing happens." The subscriber is any party that registered itself on that list. Registration usually names a type of message ("ticket available", "temperature crossed the limit") rather than one specific event, which is what makes the arrangement selective — subscribers hear about their kind of news only.
Compare the two styles directly:
| Dimension | Client-server (request-response) | Publisher-subscriber |
|---|---|---|
| Who speaks first | The client asks | The publisher notifies |
| Direction of knowledge | Client must know the server and ask | Server must know its subscriber list and tell |
| Timing | You queue and wait for your turn | News pushes out the moment it exists |
| Data volume per contact | Whatever you asked for | A light notification; details fetched separately |
| Failure style | Queue grows if server is slow | Notifications pile up if subscriber is offline |
- In client-server, you tell the server "I want a ticket," then stand in a queue. As and when your turn comes, the ticket is issued and you go back. You may work synchronously or asynchronously — either way, you asked first.
- In publisher-subscriber, there is a message that is supposed to reach you. The publishing side comes to know that something new exists — say a ticket is available. It looks up its list of subscribers for that particular service: "these are the subscribers, let me intimate them." It sends a message. Very often, receiving that message triggers a procedure at the subscriber's end which automatically fires a request back to pick up the update.
So the moment a subscriber hears from a publisher that there is an update, the request to fetch that update is triggered automatically, without a human asking. The notification works as a doorbell, not as a delivery: it tells you to come, it does not hand you the parcel.
Visualize it as a switchboard with a pegboard: each subscriber holds one peg (a registration) on the publisher's board. When news of a given type arrives, the publisher rings every peg of that type — nothing more. Add or remove a peg and nothing else about the system changes, which is why this pattern scales to many kinds of listeners without redesigning the publisher.
10.3.2 Why Notification Instead of a Data Push
A natural question follows: if the publisher already knows there is an update, why trigger a request? Why not send the data straight away?
The reason is control. Let the subscriber decide what is to be picked up, in what form, and in what detail. Everything is decided by the subscriber. The subscriber does not have to receive a huge bundle of data it does not want. Depending on the type of subscriber, the purpose of use, and the detail of use, each subscriber can be coded differently to pick up a different type of detail from the same notification. One listener fetches just the headline number, another pulls the full report, a third ignores the content entirely and merely logs the timestamp — all from one identical notification.
Real-world: this is exactly how phone notifications behave. You subscribe to notifications on your mobile phone; they keep arriving whether or not you act on them. Some apps react automatically — a notification arrives and the app triggers, shows a display, rings an alarm, or sends another message on its own. Acting on the notification is the receiver's choice, not the sender's.
Scope and pitfalls:
- Scope: subscription fits when updates are events worth announcing but payloads differ per listener. If every consumer wants exactly the same full payload every time, a plain shared repository (section 10.4) is simpler.
- Subscribing too widely floods a subscriber with messages it did not need — reference catalogs list this as the pattern's classic weakness. Subscribe to types, not to everything.
- Do not confuse this with broadcast, which sprays every message to every client whether they want it or not; subscription is broadcast's selective cousin.
- Forgetting the second leg: notification triggers a fetch. Designers who push heavy data inside notifications rebuild the client-server queue they were trying to escape.
Publisher-subscriber flips the initiative: the publisher announces to a pre-registered list, and each subscriber independently decides what, in what form, and in how much detail to fetch afterward. Watch for this exact mechanism again when the model notifies views in MVC (section 10.11).
Real-world and domain connection: stock tickers, flight-status alerts, and factory alarm systems all run on this pattern — the event source publishes once, and dashboards, phones, and loggers each pull their own slice. In enterprise software the same shape appears as messaging systems where applications subscribe to message types rather than call each other directly.
10.5 Allocation Patterns: Multi-Tier and MapReduce
Hook: The first two families asked how to cut code and how to make pieces talk. This family asks a blunter question: on which physical machine does each piece actually run? The answer changes performance, security, and even whether the computation is possible at all.
10.5.1 Multi-Tier versus Layered
Allocation patterns describe where software sits on hardware. The multi-tier pattern is different from the layered pattern, and the difference matters. Multi-tier talks a lot about mapping software modules onto hardware modules — a tier is the hardware side of the bargain: one server, or one group of servers, that hosts some of the software. A layered pattern enforces a one-way flow of traffic between layers: each layer uses only the layer below. Multi-tier allows different forms of storage and different traffic paths between tiers — a tier may host several layers at once, and traffic can flow in patterns that suit deployment rather than a strict stack.
The clean way to hold the distinction: layers are logical, tiers are physical. Layers divide responsibility inside the design; tiers divide location across machines. Three layers can live happily on one machine (one tier), and the same three layers can be spread across three machines (three tiers) without changing a line of logic — only the deployment changes. Reference texts say exactly this: layers take no account of physical location; tiers are all about it. If the distinction is not clear to you, take some trouble and look it up on the internet — the vocabulary of tiers versus layers trips many people, and mixing the two words in an exam answer is a classic slip.
| Aspect | Layered | Multi-tier |
|---|---|---|
| What it divides | Responsibilities in code (logical) | Locations in deployment (physical) |
| Traffic rule | One-way: use only the layer below | Flexible paths between tiers; tiers may host multiple layers |
| Storage | Implied by the lowest layer | Different forms of storage allowed per tier |
| Typical motive | Separation of concerns, team ownership | Scalability, security zones, offloading heavy work |
10.5.2 MapReduce: Send the Software to the Data
The most important allocation pattern in the current context is MapReduce. With the arrival of distributed computing and large database applications, the volumes involved stopped being describable in tons — and "tons" is an understatement. We normally jump from kilobytes to calling them kilos, and a thousand kilos make a ton; here we are talking about petabytes of information that need processing. A petabyte is a million gigabytes — no single machine moves that through one program's queue in useful time.
Now consider what happens if all that data must sit in a queue waiting to be processed by one particular piece of software. It will never happen. The world would wait perpetually for results. Moving the data to the software also means dragging petabytes across networks whose capacity is tiny compared with the data itself.
The inversion that fixes this: instead of getting the data to the software, send the software to the data. Wherever data lives, ship the program there and let it process the data in parallel. A large number of machines all over the world can execute a common process on data lying locally on each machine. Once each machine has processed its local share, the results are merged — reduced — and made available to whoever requires them. You mapped the program onto the data, then reduced the outputs into one result — map, then reduce. That is where the name comes from.
The procedure has a fixed shape:
- Split the dataset across many machines (usually it already lives distributed).
- Map: every machine runs the same small program over its local share, emitting partial results.
- Shuffle/group: partial results are collected by key so like items travel together.
- Reduce: grouped items are merged into final answers.
- Serve the merged result to whoever requires it.
The cost profile follows directly: the map phase scales almost perfectly because machines never talk to each other; the reduce phase concentrates traffic, so it is where systems feel strain. Open-source frameworks such as Hadoop industrialized exactly this recipe for clusters outside Google.
10.5.3 Google's Early Use at Planetary Scale
An early large-scale user of this style was Google. When you start typing a search, an enormous mechanism running across the world processes the stream of queries arriving at every instant — no single computer could stand in that river. Take the time to look up the range of services Google offers and you will be shocked: there are over a hundred completely different types of services, and a good number of them are AI services.
Google also stumbled publicly along the way: it released Bard, became the subject of jokes across the internet after some wrong answers, and later renamed the product Gemini. The renaming was not only image repair — the technology inside Gemini is apparently more advanced, and the newer releases are strong products. Google had been using what we now call artificial intelligence for a very long time before the terminology caught up; appropriate labels for these applications took years to appear.
Worked example — counting words the MapReduce way. Suppose three machines each hold one line of logs: machine A has "error disk full", machine B has "error disk again", machine C has "disk ok". Map runs everywhere locally: A emits error→1, disk→1, full→1; B emits error→1, disk→1, again→1; C emits disk→1, ok→1. Group by key collects all pairs with the same word: error arrives with two 1s, disk with three 1s, full, again, ok with one each. Reduce sums each group: error→2, disk→3, full→1, again→1, ok→1. Final answer: disk 3, error 2, again 1, full 1, ok 1. Sense-check: seven words went in and the counts sum to 7 — nothing lost, nothing double-counted. Scale that trace from three lines to petabytes and you have Google's query processing: the same tiny program executed on every machine against its local share, then reduced into one result.
Scope and pitfalls:
- Scope: MapReduce shines when the work is divisible so each machine can finish its share independently. Jobs needing global state at every step (a shared counter updated mid-computation) do not split cleanly.
- Do not write "tier" when you mean "layer" — tiers are physical homes, layers are logical responsibilities.
- The reduce step is the choke point: merging everything through too few reducers recreates the very bottleneck the map phase avoided.
- Sending software to data assumes the data already sits distributed; if your data starts centralized, moving it out is still the expensive part.
Allocation = placement. Multi-tier maps logical layers onto physical machines (tiers allow flexible paths and storage forms); MapReduce flips the data-to-software pipeline — ship the program to the petabytes, process locally in parallel, then reduce the outputs into one answer.
Real-world and domain connection: beyond search, the same pattern powers log analysis at banks, clickstream analytics at retailers, and genomic batch processing in bioinformatics — anywhere the data outgrew one machine and someone chose to move the code instead of the bytes.
10.6 Using AI Assistants as Study Tools
Hook: A study tool that remembers every question you asked it this morning — and answers the next one in light of them — is a genuinely new kind of tool. The skill is not getting access to it; the skill is using it without letting it think instead of you.
10.6.1 Stateful Chats versus Stateless Searches
There are lovely AI products available now. Bots operate on Twitter and Facebook, collating information and responding with AI capabilities. For study, tools such as Gemini, ChatGPT, and the many derivative products that embed these models as a back-end service are genuinely useful. Some of them allow only five interactions per day or another limited number — use that allowance rather than letting it expire idle.
Say you want to study the broker pattern. Open a chat on that topic. Ask questions, receive material, ask further questions, dig deeper. This works for examination preparation too. The key property that makes this powerful: conventional web searches were stateless — every search stood alone, remembered nothing about your previous search, and had nothing to do with it. Each query was a stranger walking in off the street. A chat is stateful: it generates a session, remembers your previous interactions, and responds in light of them. You never repeat yourself. That memory makes conversing with an AI tool a very effective way to discuss a subject — the conversation accumulates, like office hours with a patient tutor who never forgets what confused you ten minutes ago.
10.6.2 Practical Uses and Ownership Warnings
Concrete ways to use these tools well:
- Making a presentation, writing an essay, or writing a letter when letter-writing is not your strength? Submit the draft and ask for improvements.
- Preparing a subject? Give the tool the syllabus and ask it to summarize the syllabus for you, then ask for references.
- Want to see many component-and-connector diagrams? Ask: "please give me a few URLs where I can see component-and-connector diagrams for software architecture." It will return references, so you can focus on your area of concern.
Taken to an extreme, the tool could even do your assignment for you. Even if you go that far, take ownership of what the bot produces for you. Otherwise it becomes the emperor's new clothes: the output can make a laughing stock of you — everyone around you sees there is nothing there except you. Unintended comments land people in language that makes them look outright foolish — a large company's public AI stumble showed exactly this. Make sure nothing you submit looks like an obvious copy-paste, like ready-made material lifted from a wiki or a textbook. Chatbots even apologize when corrected — "yes, I misunderstood, sorry for misleading you" — which shows how confidently they can be wrong. An apology is not a correction of record; it is proof the earlier answer was invented. So understand every word of anything you copy from them.
Pitfalls:
- Submitting output you cannot explain sentence by sentence. If you cannot defend a line when questioned, do not ship it under your name.
- Trusting fluency for accuracy. Confident tone and correct facts are different properties; verify anything load-bearing against a textbook or lecture note.
- Wasting a scarce quota on vague prompts. A limited number of daily interactions rewards prepared questions, not idle probing.
Exam note: using AI to understand topics deeply is encouraged study behavior; submitting raw AI output without understanding it is the trap to avoid.
10.6.3 The Technology Misuse Debate
AI misuse will become a big subject, just as it has for every technology. The classical answer applies to any form of technology — it applied to fire, it applied to the bomb: it is the misuse of technology that is dangerous, not the technology itself. Whenever we hold technology, we must hold it in mature hands. History's gravest example: the order that led to Hiroshima, with over 70,000 people dead in the second bombing and countless others injured for life — a price of technology almost too heavy to judge — and yet today we depend on nuclear energy as one of the cleaner sources of power. The same invention sits at both ends of the scale; the difference is the hand that holds it.
People argue that AI is used for cheating and that students stop applying their own brains. But apply the same logic to lighting a fire: why use a matchbox or a lighter? Why not sit down knocking stones together — because you fear spoiling your habit? When a form of technology exists, the goal is to use it appropriately. A teacher guides you through a class to give you an overall perspective so you can build knowledge; an AI tool, used well, extends the same idea: read as much as you can, understand as much as you can, then rely on your own intelligence to apply the knowledge when you face the question paper.
Stateful chat sessions are the study upgrade over stateless search — pick a topic, hold the session, drill the confusion points. The ownership rule travels with you into every course and every job: whatever the bot drafts, your understanding signs it.
10.7 The Layered Pattern in Depth
Hook: What single rule turns a pile of modules into an architecture you can hand to different companies, upgrade piece by piece, and still reason about? Layering answers with one word: below. Each layer may use only the one beneath it — everything else in this pattern is a consequence of that rule.
10.7.1 Context, Problem, and Solution
Recall that a pattern is described as context, problem, and solution. For the layered pattern:
- Context: you want to evolve each module separately and independently; you want large developer teams; you want concerns separated totally — so much so that different companies can work on different layers.
- Problem: how do you divide a system so that teams never step on each other and pieces can be swapped without breaking the whole?
- Solution: stack the system into layers where each layer uses only services of the layer directly below it, and communicates through defined protocols.
The benefits follow from that separation. You can plug a layer supplied by one company together with a layer supplied by a different company. When an upgrade comes, you upgrade a single layer, and as long as it maintains the communication protocol with the layers above and below it, everything keeps working. Modifiability improves. Reuse improves. Complication drops, because not everything interacts with everything else: keep the top and the bottom interfaces common, and change anything in between freely. Once a layer's communication protocols are defined, the layer becomes a standard product that an architect in a completely unrelated environment might pick up and plug in. Reference catalogs record exactly these strengths — layers promote extension and contraction of the design — along with the matching weakness we will meet in 10.7.4: traversing many layers costs efficiency.
The construction recipe: create modules; separate the functionalities so each module holds one concern; enforce a unidirectional flow; define each block as a separate unit with its interaction protocol; then develop each module on its own. Notice the order — the protocol boundary is designed before the internals are built, which is what lets two companies build two halves independently.
Visualize the stack as a wedge of floors in a building with one staircase: floor n can send requests down to floor n−1 through the stairwell, and results come back up the same stairwell. No window between non-adjacent floors exists — and that absence is a feature, because it makes every dependency visible and countable.
10.7.2 The One-Layer Constraint and Variations
Here is the strict constraint of the layered pattern: a piece of software can belong to only one layer. Code written inside one layer cannot be used by another layer. If you want the same module in a second layer, you make a separate copy and hand it over there. And the beauty of the copy: the people working in the other layer are free to modify it however they like. It is their component now — they are not sharing anything with you. Sharing would create a hidden coupling across the boundary; copying keeps each layer self-contained, which is precisely what the pattern is buying.
Things are not always cut and dried, though. Variations exist. If some major component is needed by two layers, it can be provided as a service outside the application, and each layer uses that service. Texts also describe relaxed forms where a layer may skip past its immediate neighbor under controlled rules. There are no vanilla solutions in practice — whenever you apply a model, you adapt it.
10.7.3 Models Are Simplifications: The Physics Analogy
Why do simplified models still help? Physics class offers the perfect picture. You apply a formula the way it was taught:
where is the final velocity of the object, is its initial velocity, is its constant acceleration, and is the time elapsed. You compute how far a ball will travel and where it will fall. Then you reach college, take physics again, and are told: you forgot the air — the resistance offered by the air. All of school physics assumed a vacuum.
The formula itself is worth one line of trust-building, since every symbol must earn its place. Check the units: and are velocities (meters per second), while is acceleration (meters per second per second), so multiplying by time gives meters per second again — all three terms share units, so adding them is legal. Check the limiting case: if there is no acceleration (), the equation says — the object keeps its initial velocity forever, exactly Newton's first law. (Notation note: some books write the same equation as ; the lecture uses for the starting velocity.)
Worked example — the school-physics prediction. A ball rolls off a ramp with initial velocity and decelerates on rough grass at a constant . How fast is it moving after ? Apply the model: . Final velocity after 1.5 s is 2 m/s. Sense-check: the speed dropped from 5 toward 0, and continuing at the ball would stop at — so being down to 2 m/s at 1.5 s fits. The prediction is clean, deterministic, and slightly wrong about the real lawn — grass, wind, and ball spin are all left out. That "slightly wrong but thinkable" quality is the entire point of the analogy.
We build models in vacuums. We build them to gain a vocabulary and a basis for thinking about what happens. It is not necessary that reality matches the model exactly — and that is fine. The same holds for architectural patterns: the vanilla form gives you the vocabulary; the real system always adds friction the model left out.
10.7.4 The Cost of Layering
Layering is not free. Earlier separation adds cost, and you must stay constrained by it. Picture a company: top management, middle management, supervisors, workers. If a worker wants something sanctioned by the board of directors, the request must pass through every stage. Call it a weakness: decisions take a long time, and sometimes information does not even cross sideways. So be it — without that structure the organization would not function at all. You accept the costs of the form. Layered software carries the same performance penalty — every request pays a traversal tax through each intervening layer — and you cannot wish it away.
Worked example — the class-representative tree. In physical classrooms, when information had to reach every student, faculty created a tree structure: inform two class representatives — normally one man and one woman — and each representative passes the word to two more people, and so on. Trace a class of, say, 31 students: faculty tell 2 representatives, those 2 each tell 2 more (4), then 8, then 16 — and students hear the message through just four hops instead of the faculty dialing 30 times. The fragility is obvious once drawn: if any one link breaks, that entire branch fails — the 16 students below a broken link hear nothing. The fix was procedural: if a link cannot deliver, tell the sibling link "either get across to that person or inform the next level yourself." Information took longer to travel — this was an era without WhatsApp groups or social networks — but it did get through. It was a world where even reaching someone on a landline was a luxury. The tree worked, slowly, and its costs were accepted — exactly like the costs of a deep layer stack: predictable delay bought for organizational clarity.
Pitfalls:
- Believing layering removes complexity. It moves complexity into interface design; bad interfaces make the stack worse than the tangle it replaced.
- Letting a "small shortcut" bypass a layer quietly. One bypass breaks the guarantee that made reasoning about the stack possible, and soon nobody knows what talks to what.
- Copying a shared module into two layers and then "helpfully" keeping the copies synchronized — that reintroduces the cross-layer coupling the copy was meant to remove.
- Expecting vanilla performance from deep stacks: more layers mean more hops per request, and the tax is real.
10.7.5 Why Classic Patterns Still Matter
Someone asks: in a generation of microservices, tablets, and cloud computing, why discuss these old applications at all? The reality is that all these older technologies and techniques exist today, and even the most advanced services use these patterns in their building blocks.
Two analogies nail it. However complex the music, you still need your do, re, mi, fa, so, la, ti, do — or sa, re, ga, ma, pa, dha, ni, sa. With the most complex English constructions, you still need your ABC and your grammar constructs. People mangle English with slang and variations, but even to slang it well you must know the language. With patterns: learn the classic patterns to understand whatever patterns — or non-patterns — you work with today.
Q: What is a good example of the unidirectional flow in the layered pattern? A: The internet protocol stack. Data moves right from the application layer, through TCP/IP, down to the physical layer — a typical and most popular example of layering. A computer science degree usually dedicates a whole course to it, often named computer networks; the first course in networks is essentially the layered pattern. On the receiving end, the same layered pattern runs in reverse order, peeling the layers back up.
Layered = strict one-way use, one home per module, copies instead of shared code, protocols fixed at the boundaries. Buy it for independent evolution and team scale; pay for it in traversal cost. And when reality refuses to match the vanilla model, remember the vacuum: the model was never supposed to be the world, only the vocabulary for thinking about it.
Real-world and domain connection: operating systems, network protocol stacks, and software product lines are the canonical layered deployments — kernel below, drivers above, applications on top — and every major cloud platform still ships its services arranged in exactly such stacks.
10.8 The Broker Pattern and Its Proxy
Hook: If the broker is the busy meeting point everyone must reach, who handles all the small errands on your side of town so you do not have to cross the city for each one? That local helper is the proxy — the broker pattern's quiet companion.
10.8.1 What a Proxy Does
Broker solutions often come packaged with the concept of a proxy — a stand-in component that sits on the client's side and acts on the client's behalf. The everyday sense helps first: in school, "proxy attendance" meant someone marked attendance for an absent friend. The legal version: company shareholders who cannot attend a meeting appoint a proxy to vote for them. With online voting, people collect proxies so they arrive holding, say, proxies from 51% of the shareholders — and can tell the room, "you better sit and listen to me." In every version, one party carries another's authority so the principal does not have to show up.
In the broker pattern, a proxy makes communication easy in front of the broker. You do not have to go beyond the proxy for information that does not relate to the broker's core job. Three jobs fill that description:
- Cache: the proxy remembers answers close to the requester. Once it has fetched something, repeat requests are served locally — faster, and without loading the broker.
- Converter: it can convert data intermittently into a form the broker can use as it likes — translating formats at the edge so neither end has to speak the other's dialect.
- Local agent: it renders lots of local services on the client's behalf — queuing, buffering, small housekeeping — so the client deals only with its neighbor.
Visualize the arrangement as a shop counter at the end of your street: most needs are met right there from stock on hand (the cache), odd-sized orders get repackaged before being sent onward (the converter), and parcels you hand over are held until the delivery truck comes (the local agent). Only genuinely central business travels all the way to the broker.
10.8.2 Mail Proxies and Web Proxies
Mail proxies show the idea at its most useful. Local mail gets distributed directly by the proxy without ever reaching the mail server. When the internet connection is down, the mail proxy holds all outgoing mail; the moment the server becomes reachable, the proxy pushes everything through. Clients do not have to stay logged in: a client simply hands its mail to the mail proxy and logs out. This was one of the major early uses of a proxy server.
Worked example — tracing a mail proxy through an outage. Say fifty employees send mail during a network outage at 10:00. Each client hands its message to the local mail proxy and logs out — no waiting, no error dialogs. The proxy accumulates all fifty messages in its outgoing queue. At 11:30 the link to the mail server recovers; the proxy detects reachability and pushes all fifty messages through in order, then fetches inbound mail and distributes it directly to local inboxes without each client re-connecting. Result: zero lost mail, zero clients kept online, one connection burst instead of fifty. Sense-check: count the roles — holding mail during the outage is the local-agent job, batching into the server's preferred form is the converter job, and any previously fetched address-book or directory answers served locally are the cache job. Every behavior maps onto the three proxy duties from 10.8.1.
Web proxies are the other common case: access to the internet itself may route over a proxy — pages fetched once for one user are cached and served to the next user who asks for the same page, which is why organizations run them both for speed and for controlled access. Various broker solutions exist beyond these; going through them at leisure rounds out the picture.
Pitfalls:
- Treating cached answers as forever-fresh. A cache serves convenience; stale entries near their expiry are the price. Know what freshness your use demands.
- Assuming the proxy removes the broker bottleneck. It shrinks traffic toward the broker but adds its own busy point on the client side.
- Making the proxy do core business logic. The moment decisions belong at the center, they belong at the broker; the proxy should stay errand-grade.
Proxy = the client-side companion of the broker: cache what was fetched, convert what differs, render local services so clients need not stay connected. Mail and web proxies are the classic instances — hold, forward, remember.
Real-world and domain connection: content delivery networks run the same play at planetary scale — edge servers cache and convert close to users so the central origin (the broker of content) handles only what truly needs central attention.
10.9 Pipes and Filters in Depth
Hook: Your house plumbing does not care what flows through it — water is water, and any fixture fits any pipe. What if software units were as interchangeable? Pipes and filters answers by making the joint, not the unit, the standard.
10.9.1 Streams, Transformations, and Compatibility
The context of pipes and filters: a stream of data moves from module to module, the output of one becoming the input of the next, and inside each module a single transformation takes place. Unix commands are the canonical example. Each command handles one particular activity: one sorts, one merges, grep filters out matching data, one reads data from the console, one compares two files. You chain them so things flow from one to the other along the common data pattern.
The engineering duty that makes it work: compatibility of data between one module's output and the next module's input. You design your blocks, and you design the structure of the data that moves through the pipes, so every joint fits. This is where the discipline lives — a pipeline is only as interchangeable as its data contract is uniform. The processing modules can fork out into parallel branches, fork in, and join again, so the shape need not stay a straight line. We call each processing module a filter — it does something to the data passing through.
Visualize an assembly line at a bottling plant: empty bottles enter a shared conveyor (the stream), each station performs exactly one operation — rinse, fill, cap, label — and because every station grips bottles the same way, stations can be inserted, removed, or reordered without stopping the line.
Worked example — a Unix command chain. Suppose a file orders.txt holds one purchase per line, and you want the three most frequent product names. Build the pipeline:
grep -v "^#" orders.txt | sort | uniq -c | sort -rn | head -3
Trace the data stage by stage: grep -v "^#" drops comment lines (filter 1: select); sort puts identical product names next to each other (filter 2: order); uniq -c collapses adjacent duplicates into counts (filter 3: aggregate — it can only work because sort made duplicates adjacent, which is compatibility in action); sort -rn orders by count, largest first (filter 4: rank); head -3 passes only the top three lines onward (filter 5: truncate). If orders.txt contains 1,000 lines with pen appearing 120 times, nib 90 times, and ink 70 times, the screen shows exactly those three names with their counts. Final answer: a three-line ranked list produced by five single-purpose units that know nothing about each other. Sense-check: remove any one filter and the chain fails or degrades in a predictable way — proof that each unit owned exactly one transformation.
Q: How is error handling handled in a pipes-and-filters chain? A: Look at how Unix handles it: every filter throws its own error. Each stage owns the failures of its own transformation. And in certain cases a filter does not even allow data to pass onward — it stops the stream rather than forward bad data.
10.9.2 Worked Application Scenarios
Three application shapes show the pattern's range:
- Voice processing. Route the signal through filters, each performing one transformation on the stream — noise removal, then echo cancellation, then compression — none of which needs to know another exists.
- Forms and documents. A document moves from stage to stage, each stage performing one function — validation, extraction, formatting — until it emerges processed.
- Visa applications. Large numbers of applications arrive. Specialized modules process them in sequence, and those modules can carry local storage, holding data once taken in before releasing it toward the output and the next unit — a filter that buffers, useful when upstream stages produce faster than downstream ones consume.
You may also rearrange the order of the units, for several reasons. Maybe a bottleneck is forming somewhere. Maybe placing a particular stage earlier means a lot of data gets filtered out in advance, so the next stage carries a lower load. Load balancing and early filtering are the usual arguments for reordering the pipeline. In the visa flow, moving document-completeness checking to the very first stage means incomplete applications never occupy the expensive verification stages behind it — same filters, different order, materially different throughput.
Pitfalls:
- Building pipelines whose joints are secretly non-uniform — one stage emitting slightly richer data than the next accepts. The failure surfaces far from its cause.
- Letting one filter quietly do two jobs. Interchangeability dies the moment a unit's transformation stops being single-purpose.
- Ignoring back-pressure: if a downstream filter consumes slower than upstream produces, something must buffer or throttle, or memory grows without bound.
- Reordering stages without checking dependencies — some transformations presuppose inputs only earlier stages can guarantee.
Pipes and filters = uniform streams plus single-transformation filters. Design the joint first and the units become plug-compatible; own errors locally; reorder freely for load balancing and early filtering. When you meet a long Unix command or a document-processing workflow, name the joints before reading the units.
Real-world and domain connection: media-encoding pipelines, ETL (extract-transform-load) jobs in data warehouses, and compiler passes — lexing, parsing, optimizing, code generation — are all industrial pipes-and-filters systems where each stage's output format is the next stage's contract.
10.10 Adapter versus Broker
Hook: Two classic connector patterns, both sitting "in between" two parties — so are they the same thing wearing different names? One student question untangles them for good.
10.10.1 Student Question and Full Answer
Q: Is an adapter the same thing as a broker? A: Definitely not. A broker puts a large number of people in touch with a large number of people — many on one side, many on the other, meeting at one point. An adapter connects dissimilar interfaces; it is like a translator. A broker could have an adapter attached to one of its limbs, which shows they are different animals that can cooperate.
The translator story makes the difference vivid. A gentleman flies down from London to meet local political leaders who may not know English. They fix an appointment and meet in a five-star hotel. One rattles on in English, the other rattles on in Bengali, and neither understands the other. Is a broker required to resolve this? No. A broker would be needed if large numbers of people in England wanted to interact with large numbers of leaders here — scale on both sides is the broker's job. But even after fixing a broker, you might still need an adapter: somebody who listens to the Englishman and translates into Bengali, listens to the Bengali gentleman and translates into English. That person converts between two incompatible languages — that is the adapter.
| Dimension | Broker | Adapter |
|---|---|---|
| Problem solved | Many-to-many meeting at scale | Two incompatible interfaces |
| How many parties | Many on each side | Exactly two endpoints |
| What it knows | Who exists and where (registration) | Both dialects in detail |
| Failure mode | Bottleneck, single point of failure | Conversion gaps for untranslatable requests |
| Relationship | Can employ an adapter at one limb | Can sit attached to a broker |
When to pick which: if the pain is finding and coordinating many parties, broker; if the pain is two specific parties speaking incompatible formats, adapter — and large systems routinely use both at once.
10.10.2 Building an Adapter Between Two Systems
In software terms: sometimes established systems are available in the market, or components that are well-known and sturdy — but their interfaces do not match. Suppose everything system A requires can be deciphered from the output of B, and everything B needs as input can be deciphered from the output of A. Then you write a component that takes the input coming from A, converts it, and feeds it to B in the format B expects. In reverse, when output arrives from B, the component takes it, performs the conversion, and provides it in the format A requires. That component is the adapter pattern. One converter, two directions, zero changes to either established system.
Worked example — adapting an old inventory system to a new ordering portal. The legacy warehouse system B only understands flat records like ITEM|QTY|LOC (for example PEN|120|A3), while the new web portal A sends JSON like {"sku":"PEN","count":120,"shelf":"A3"}. The information content matches field for field — that is the precondition ("everything A requires can be deciphered from B's output", and vice versa). Build one adapter component with two directions: portal-to-warehouse, it parses the JSON and emits PEN|120|A3; warehouse-to-portal, it splits the pipe-delimited line and emits the JSON object. Trace one order: portal posts JSON → adapter rewrites → warehouse replies PEN|118|A3 → adapter rewrites back to JSON → portal displays stock 118. Final answer: full interoperability with neither the portal nor the warehouse modified by a single line. Sense-check: try an item missing in B ({"sku":"XYZ"}) — the adapter cannot invent data, so it must surface a clean error rather than fabricate fields; knowing where conversion is impossible is part of the adapter's job.
Pitfalls:
- Calling any middleman a broker. Middlemanship is not the test; many-on-many coordination versus two-party translation is.
- Letting an adapter grow business rules. The moment it starts deciding what should happen instead of translating how things are said, it has become a third system nobody designed.
- Assuming translation is always total. Some concepts in one interface have no counterpart in the other; adapters need explicit failure behavior for those cases.
Broker = scale (many meets many at one registered point); adapter = translation (two dissimilar interfaces, converted both ways). They are different animals that cooperate — a broker may keep an adapter on its limb, but neither replaces the other.
Real-world and domain connection: payment gateways that translate between a shop's checkout format and card-network protocols, and USB power adapters between wall sockets and devices, are everyday adapters; travel-booking platforms brokering between thousands of fliers and hundreds of airlines are everyday brokers.
10.11 Model-View-Controller in Depth
Hook: One body of data, a dozen audiences, a dozen formats, a dozen delivery channels — and nobody may click "refresh". How do you show the same data in many different ways without building a complicated presentation system? MVC is the answer, and a factory floor makes it concrete.
10.11.1 Motivating Scenario: The Automated Factory Floor
Walk through the factory scenario that motivates the pattern.
You run a factory. All the important data about the factory is available and updated from various sources. Transducers feed it in — a transducer is equipment that takes input in one form and converts it to another: temperature, pressure, humidity. Reports arrive. Certain systems push data: the sales system, the production system. Critical information, computed by certain processes, displays on large panels on the factory shop floor, totally automated — nobody decides what should show; the rules decide. Alarms trigger off in the factory when temperatures leave a safe range or fire is detected, and announcements go out. Departmental managers get summary reports, appearing automatically in their mailboxes, or on the console, or overriding whatever they were doing as an alert — the system handles interrupts that drive these displays. Some reports are available only on request. Notifications go to the mobiles of registered people, telling them updates are available. Some open screens viewing the data update automatically — the numbers change on screen while you watch, no clicking needed. Graphs render live. The CEO gets a summary report and probably keeps a wall screen showing major updates and yesterday-versus-today positions.
That is the context: one body of data, many audiences, many formats, many delivery channels. Sort the audience list and a pattern emerges:
| Audience | Format | Channel | Update style |
|---|---|---|---|
| Shop floor | Big numeric panels | Wall displays | Automatic, rule-driven |
| Everyone nearby | Alarm text/announcements | Speakers, sirens | Triggered by thresholds |
| Department managers | Summary reports | Mailbox, console, interrupt alerts | Scheduled or pushed |
| Registered staff | Update notices | Mobile notifications | Pushed on change |
| Analysts | Graphs, live numbers | Open screens | Auto-refreshing |
| CEO | Summary, day-over-day | Report plus wall screen | On demand plus live |
Six different faces, one underlying set of facts. Building each face as its own little system with its own copy of the data would guarantee inconsistency; the fix is to separate what is known from how it is shown.
10.11.2 Roles and Interactions
Who wants to see what, and how they want to see it, is a user-interface problem. The user interface has a program that fetches data. To fetch it, the view informs the model: "I am interested in this class of data." The controller mediates between the model and the views. Instructions can flow from a view to the model — "give me this data." When users input data, the controller receives it and updates the model.
So the cast is: a distinct group of software modules called views — possibly a huge variety, with totally dissimilar natures of application — all accessing data from a common model, which is designed to provide the varying types of information required, and more. The controller takes instructions either from the views or from input devices, and updates the model accordingly. Any state change flows through the controller to the model; the view can make gestures and give options, which go to the controller; the controller updates the model; and the view can query the model when it needs current state.
Worked example — tracing one temperature reading through the trio. A furnace-area transducer reports 415 °C against a safe limit of 400 °C. Model: the new reading enters the common data store; the model notices subscribers to temperature-class data. Controller: an operator at a console acknowledges the alert and sets a reduced production rate — that instruction goes to the controller, which validates it and updates the model's operating-rate field. Views: the shop-floor panel re-renders 415 °C in red; the alarm subsystem fires the announcement; the manager's mailbox receives a threshold-exceeded summary; registered mobiles get "update available" notices; the analyst's live graph appends a point; the CEO wall screen moves its yesterday-vs-today marker. Final answer: six reactions from one stored fact, with no view ever writing data directly. Sense-check: every arrow in the trace respects the role law — writes pass through the controller, reads go to the model, and notifications flow from the model outward.
10.11.3 Change Notification as Publisher-Subscriber
Here is the connection worth remembering: the change-notification side of MVC is the publisher-subscriber aspect. The model and the views interact as publisher and subscribers where notifications are concerned. All views register with the model — they tell it, "listen, I'm subscribing." If the parties are operated by different companies, there could even be a subscription fee; within one company, it is just a question of having the technology in place. The model notifies all subscribers when state changes.
It behaves like subscribing to notifications on your mobile phone: notifications keep arriving whether or not you act on them. Applications on the phone can also be triggered automatically by a notification — a display appears, an alarm rings, another message goes out. Whether and how to react is the receiver's decision. Likewise each view takes independent decisions about what to do with a change notification — the panel repaints, the graph appends, the mailer composes, all independently, from the same notification.
10.11.4 Independence, Security, and Diagram Conventions
Look at how departmentalized and simple the whole application has become. The model worries about its subscribers and notifying them, plus keeping certain ports available where it accepts queries. Those queries can arrive over a secure line; they can require user ID and password — meaning a state query may need identification, so the model authenticates the requester and only then responds. The model is a completely separate box. It could be developed by a separate company. The views simply use the benefits of the model.
The controller is the socially coupled member: its design normally has a lot to do with the view. The controller provides certain facilities, and if it was built with particular features, the view uses those features to inform the controller of whatever needs informing. Various solutions exist for wiring this trio; reading through them in detail pays off.
Q: In the MVC diagram, what is the dotted line? A: Dotted lines are used for return messages. Solid arrows carry calls and updates outward; dotted arrows carry the responses coming back.
Pitfalls:
- Letting a view write the model directly. That bypasses validation and breaks the umpire role of the controller — every state change must route through it.
- Making the model know about specific views. The model should hold data and notify subscribers generically; the moment it names a view, reuse dies.
- Forgetting that the controller–view pair is deliberately chatty while the model stands apart — expecting the controller to be as standalone as the model misreads the design.
- Treating MVC as only a GUI trick. It is an information-separation pattern: any "one dataset, many presentations" problem fits.
MVC = one model owning the data, many views rendering it, one controller policing changes. Its notification half is publisher-subscriber wearing a user-interface costume — register, get told, react your own way. When an exam shows a factory-floor-style scenario, map each audience to a view before designing anything else.
Real-world and domain connection: web frameworks popularized MVC for browser applications — routes act as controllers, templates as views, database-backed objects as models — and monitoring dashboards for power grids and trading floors are factory-floor scenarios in modern dress.
10.12 Service-Oriented Architecture in Depth
Hook: You have used an architecture pattern every time you booked a cab without once thinking about satellites. Service-oriented architecture is the discipline of letting strangers build on your application without ever showing them inside it.
10.12.1 Providers, Consumers, and the Uber Example
Service-oriented architecture separates service providers, who offer services, from consumers, who need to consume them. The clean example: Uber consumes the service provided by Google Maps. Uber does not need to understand what Google is doing internally — whether they run one satellite, two satellites, or fourteen satellites is not Uber's problem. How data comes down from the satellites, what triangulation is performed, how readings from three satellites determine the latitude, longitude, and altitude of a point — none of that is Uber's concern. Uber knows only this: if I make a request to Google in the agreed format, Google provides the service. Provider and consumer are completely separate, and the consumer needs to know only what information to supply to get the response.
Reference texts state the same separation as design tenets: boundaries are explicit (crossing into a service costs a network hop, so it is designed deliberately), services are autonomous (each side deploys and evolves independently), the two sides share schemas and contracts rather than code, and compatibility is governed by published policy. Every one of those tenets is visible in the Uber–Google pair: the contract is the request format; the policy is authentication and usage terms; the internals on both sides can be rewritten overnight without the other noticing.
Worked example — tracing one ride request through provider and consumer. A rider taps "book" in the Uber app standing at a street corner. Consumer side: Uber's system composes a request in the agreed format — current location coordinates plus desired map view — and sends it to the Google Maps service endpoint. Provider side: Google receives the request, consults its positioning machinery — satellites overhead, triangulation across readings from three of them to fix latitude, longitude, and altitude — and returns a rendered map and route data. Back at the consumer: Uber overlays car positions and fares on the returned map and shows the rider the nearest vehicle. Final answer: a completed booking where the consumer never learned that satellites exist, and the provider never learned that rides exist. Sense-check: swap Google's internals for any other positioning technology honoring the same contract and this trace runs unchanged — which is exactly the independence the pattern sells.
10.12.2 Services on Your Own Website and Commercial Models
The consumer side is open to anybody. Even for a personal website, you can configure access to services Google offers free of cost: write code in your web application that pulls data from Google Maps and overlays your own data on top of it. Write the directions to your office. Show the address of each of your offices worldwide, the contact person at each location, a guide to traveling to your office — one click on your website opens a page that guides a visitor there. Limited coding, free of cost, full interoperability benefit: Google developed the Maps application, and you offer its facilities as a service inside your own pages.
That is the pattern in one sentence: a service-oriented architecture distributes the facilities of an application to various people, so they may access it as a service. They do not buy the application from Google — they access it as a service. The commercial side flexes: the service could be free, chargeable monthly, charged per use, or billed on the quantum of data downloaded. Carry the concept forward and everything becomes available as a service eventually — infrastructure, platform, operating system: everything as a service. The essence is an architecture that offers any facility as a service to a large number of users, dissimilar users, for different purposes, across the internet.
Consumers can be other companies accessing over a browser, or email clients, or booking flows: a customer booking a hotel, airline, or bus ticket uses bank services to pay by credit card, and beyond the bank may touch authentication services from Visa or MasterCard. All those interactions are basically services talking to services — a single checkout quietly orchestrating half a dozen providers while the customer watches one screen.
10.12.3 Concrete Technologies and the Rise of APIs
Named examples ground this. Microsoft Communication Foundation and Microsoft Web Services: you write your services inside, they access your database, you write queries and call procedures inside the code, and you expose the result against a URL for users. That is a service-oriented architecture in practice — the URL is the contract's front door.
APIs have since become a subject in themselves — people specialize in API work — and at the base of API use sits a service-oriented architecture. Reference texts add the standards layer beneath such tooling: description languages that publish what a service offers, directories where services can be found, and message formats carried over ordinary web protocols. You do not need the acronym soup to grasp the shape: describe, discover, invoke — all through messages, never through shared code.
10.12.4 Facade versus Service-Oriented Architecture
Q: Can we say we are using a facade to expose and use services? A: Yes, in a way. Normally we use a facade class to interact with other modules, and if one particular class handles all requests coming from outside, you can call that a facade class. But normally a facade would be part of subsystems. A service-oriented architecture may have a lot of subsystems inside it, and each one may have its own facade. We reserve the word facade for subsystems talking to each other; when a full system is put together for use by larger external blocks, we call it a service-oriented architecture.
Language precision matters here. When you describe something in its vanilla form, these terms apply cleanly and help mutual understanding. In a complex system, terms blur — it becomes a question of understanding each other. When you say facade and I say SOA, as long as we express ourselves to one another, it is perfectly in order.
Exam note: examination scenarios keep this simple. Questions are framed so the terms apply cleanly — not as tangled as the real world, where meanings sit on the borderline, like writing a storybook where language bends. You cannot have everything black and white.
10.12.5 Frameworks and Adapters in Practice
A shared-screen example tied the threads together: instead of accessing a logger directly, access an ILogger interface. Various logging implementations sit behind one common interface, and clients depend on the interface, not the concrete logger — an adapter-style move that decouples callers from implementations. Swap file logging for network logging and no caller changes a line, because the contract never moved.
Frameworks deserve their own definition. Development companies build patterns into frameworks. A framework is a large aggregation providing a controlled environment that can be used without having to reinvent the wheel — the structure, conventions, and plumbing come ready-made, and you fill in your part. Where a library waits for you to call it, a framework calls you: it owns the program flow and hands you the empty slots.
10.12.6 Open Platforms and Standardized Protocols
This style of integration has become a standard. Lots of platforms make their services available, so their communication protocols have had to be standardized. Travel is the visible case: MakeMyTrip, Yatra, EaseMyTrip, ClearMyTrip all interoperate with the same suppliers, which tells you the protocols are shared. The umbrella terminology is open platform communication. Every industry ends up with a protocol. Governments, too: the Government of India now receives a great deal of data using standardized protocols.
On the wire format: JSON is in popular use. Earlier, communication meant flat files with comma separators. Now that more people work in the object-oriented world, XML-based protocols appeared, and JSON is in major use. Banking shows how far standardization goes: enormous documentation exists, and banks' data-communication protocols are standardized — not only by RBI in India, but as international standards. Communicating over open platforms with common protocols has become fundamental to modern integration.
Pitfalls:
- Treating a service as a remote function call. Crossing the boundary costs latency and fails differently; designs that ignore the boundary pay for it in fragility.
- Sharing implementation details instead of contracts. The moment consumers depend on your internals, autonomy is gone and every internal change breaks them.
- Letting version drift silently. Providers evolve; backward-compatible contracts and published policies are what keep unknown consumers working.
- Using "facade" and "SOA" interchangeably in answers — keep facade for subsystem boundaries, SOA for whole systems offered externally.
SOA = providers behind explicit contracts, consumers who know only the request format, and commercial models from free to per-byte. Facades belong inside subsystems; the whole-system offering to external blocks is the service. Follow the chain far enough and infrastructure, platforms, even operating systems arrive as services.
Real-world and domain connection: every major cloud platform is SOA industrialized — storage, messaging, payment, and mapping are consumed as metered services by millions of applications, exactly the free-to-paid spectrum and per-use billing described above.
Exam Guidance Summary
- Assignment guidance: identify patterns and bring out the discussion on patterns vividly and in full; cover everything that is asked for. Whatever else you do well, the pattern discussion is the flagged item.
- Sequence diagrams: describing one scenario as a sequence diagram is asked for, and it is not covered in class sessions. Go through the supplementary video session on drawing sequence diagrams (interaction diagrams). The goal is to express the dynamics of an application — an interaction scenario showing how the application pans out, message by message between components — not the quality scenarios studied elsewhere in the course. Most working students have met sequence diagrams already; if not, one focused self-study pass is enough.
- Question framing: exam questions are kept simple relative to the real world. Terms apply in their vanilla forms. Do not overcomplicate; recognize which pattern the question describes and state its benefits — the two-step reflex from section 10.1 is exactly what is being tested.
- Study approach: the subject is vast — almost impossible to pin to a syllabus. Read as much as you can, understand as much as you can, then apply your intelligence to the question paper. Marks follow from applying knowledge, not from memorizing boundaries.
- Self-study pointers: look up multi-tier versus layered on the internet if unclear; read through the various broker solutions at leisure; read the detailed MVC and SOA solution variants in the course material.
- Tooling advice: use limited-quota AI chat sessions deliberately for exam preparation — pick a topic, hold a stateful conversation, drill into confusion points.
Exam note: for every pattern question, answer in two moves — name the vanilla pattern, then state its benefits (and where asked, its costs). For scenario questions, map each described component to a role before writing anything else.
Key Industry Applications
- Google — early MapReduce-scale user; search query processing distributed worldwide; over a hundred distinct services, many AI-based; Bard renamed Gemini after public missteps.
- Uber + Google Maps — the canonical service provider/consumer pair: Uber consumes mapping as a service without knowing satellite or triangulation internals.
- WhatsApp and torrents — peer-to-peer examples; torrents truly decentralized, WhatsApp nominally so.
- Dropbox, OneDrive, Google Drive — shared file services replacing local storage servers in non-IT companies.
- Twitter and Facebook bots — AI-driven information collation and response.
- Gemini and ChatGPT — stateful AI chat sessions used as study aids; derivative products embed them as back-end services.
- Unix command pipeline — sort, merge, grep, console readers, file comparers as filters joined by pipes.
- MakeMyTrip, Yatra, EaseMyTrip, ClearMyTrip — standardized open-platform communication in travel.
- Microsoft Communication Foundation and Microsoft Web Services — services written against databases and exposed at URLs.
- Visa and MasterCard — authentication services consumed during card payments inside booking flows.
- RBI and international banking standards — standardized bank data-communication protocols.
- JSON and XML — modern structured interchange formats replacing comma-separated flat files.
- TCP/IP protocol stack — the layered pattern's most famous instance, from application layer down to physical layer.
- ILogger-style logging interfaces — adapters decoupling clients from concrete implementations behind a common interface.
Each entry above is a named instance of a pattern from this lecture: when revising, walk the list once and recite which pattern each company or technology illustrates and what benefit that pattern was bought for.
SA Lecture 10 notes · Architectural Patterns: Catalogs, Styles, and Case Studies
Sections Breakdown
Patterns are organized into three families — module (how code is split), component-and-connector (how pieces interact), and allocation (where software maps onto hardware) — and the architect's core skill is naming a pattern from its structure and stating its benefits.
A quick tour of the connector family: layered, broker, MVC, pipes and filters, client-server, peer-to-peer, and SOA, each recognized by its vanilla shape with one benefit and one cost attached; real systems combine several patterns at once.
Publisher-subscriber reverses request-response: subscribers register for message types, the publisher notifies the list when news exists, and each subscriber independently decides what to fetch, in what form and detail.
Shared-data places one repository — file system, object storage, RDBMS, or NoSQL — and lets many users read and write through the data itself, with no direct messaging between producers and consumers.
Allocation patterns place software on hardware: multi-tier maps logical layers onto physical machines with flexible traffic paths, while MapReduce inverts data processing by sending the software to petabyte-scale data and reducing local results into one answer.
AI chats are stateful sessions that remember prior interactions, unlike stateless web searches, making them powerful study drills — provided you take ownership of every word and treat misuse of the technology, not the technology itself, as the danger.
The layered pattern stacks modules so each uses only the layer below, buying independent evolution and company-scale separation at the price of a traversal tax; simplified models like v = u + at show why vanilla forms are worth keeping even though reality adds friction.
A proxy stands in front of the broker on the client's side: it caches answers close to the requester, converts data into forms the broker accepts, and renders local services — mail proxies holding outgoing mail through outages are the classic worked case.
Pipes and filters chains single-transformation filters over a uniform data stream so units stay interchangeable; Unix command pipelines are canonical, errors are owned per stage, and stages may be reordered for load balancing or early filtering.
A broker coordinates many parties on each side at one meeting point; an adapter translates between exactly two dissimilar interfaces in both directions — different animals that can cooperate, since a broker may carry an adapter on one limb.
MVC separates one model (the data store) from many views (presentations) with a controller mediating all state changes; the model's change notification to registered views is publisher-subscriber in user-interface clothing.
SOA separates providers behind explicit contracts from consumers who know only the request format — Uber consuming Google Maps without knowing satellite internals is the canonical pair — with commercial models from free to per-byte and standardized open-platform protocols underneath.
Consolidated exam guidance: pattern identification with vivid full discussion is the flagged assignment item; sequence diagrams are self-study via the supplementary session; questions stay vanilla-simple; study broadly and apply intelligence rather than memorizing boundaries.
Named industry instances mapping one-to-one onto the lecture's patterns: Google (MapReduce), Uber plus Google Maps (SOA), torrents and WhatsApp (peer-to-peer), Unix pipelines (pipes and filters), TCP/IP (layered), travel platforms and banking protocols (open-platform SOA).
Exam Revision Notes
Below is the distilled, exam-ready core. Every entry comes from the full explanation above. Use this section for rapid review; return to the main notes when a point needs more context.
Three Ways to Catalog Patterns
Must-know: The three pattern families and one example of each: module (layered), component-and-connector (broker, MVC, pipes-and-filters, client-server, peer-to-peer, pub-sub, shared-data, SOA), allocation (multi-tier, MapReduce).
⚠️ Top pitfall: Treating families as mutually exclusive — real systems mix patterns from all three families.
Self-check: Which family does MapReduce belong to, and what question does that family answer?
Connects to: §10.2 A Guided Tour of Component-and-Connector Patterns, §10.5 Allocation Patterns: Multi-Tier and MapReduce, §10.7 The Layered Pattern in Depth
A Guided Tour of Component-and-Connector Patterns
Must-know: Each connector pattern's vanilla form plus its benefit and cost: broker gives location transparency but can bottleneck; client-server centralizes control; peer-to-peer removes the single failure point; SOA wraps legacy applications as services.
⚠️ Top pitfall: Judging a pattern by one property only — every pattern trades a benefit for a cost.
Self-check: Why keep a broker despite the bottleneck risk? (No duplication of work, maintained consistency, proper allocation of resources.)
Connects to: §10.1 Three Ways to Catalog Patterns, §10.7 The Layered Pattern in Depth, §10.8 The Broker Pattern and Its Proxy, §10.9 Pipes and Filters in Depth, §10.11 Model-View-Controller in Depth, §10.12 Service-Oriented Architecture in Depth
The Publisher-Subscriber Pattern
Must-know: Notification triggers an automatic fetch request at the subscriber; the subscriber decides what/form/detail — that control is why publishers notify instead of pushing data.
⚠️ Top pitfall: Confusing pub-sub with broadcast (broadcast is not selective) or pushing heavy data inside notifications.
Self-check: Why does receiving a notification usually trigger a follow-up request instead of carrying all the data?
Connects to: §10.2 A Guided Tour of Component-and-Connector Patterns, §10.4 The Shared-Data Pattern, §10.11 Model-View-Controller in Depth
The Shared-Data Pattern
Must-know: Shared-data = one repository, many users, coordination happens entirely through the data; legitimate when data availability is the core requirement.
⚠️ Top pitfall: Using it when updates must be pushed instantly — that calls for publisher-subscriber instead.
Self-check: How does shared-data differ from publisher-subscriber in who initiates contact?
Connects to: §10.3 The Publisher-Subscriber Pattern, §10.5 Allocation Patterns: Multi-Tier and MapReduce
Allocation Patterns: Multi-Tier and MapReduce
Must-know: Layers are logical, tiers are physical; MapReduce = send the software to the data, process locally in parallel, then merge (reduce) the outputs.
⚠️ Top pitfall: Mixing up tier and layer vocabulary, or forgetting that the reduce/merge step is where bottlenecks reappear.
Self-check: Why not queue all petabytes through one program? What is inverted instead?
Connects to: §10.1 Three Ways to Catalog Patterns, §10.7 The Layered Pattern in Depth
Using AI Assistants as Study Tools
Must-know: Stateful chat remembers session context (searches do not); use limited-quota sessions deliberately; understand every word you submit.
⚠️ Top pitfall: Submitting raw AI output you cannot explain — confidently wrong answers come with apologies, not corrections.
Self-check: What property separates an AI chat from a conventional web search?
Connects to: §10.2 A Guided Tour of Component-and-Connector Patterns
The Layered Pattern in Depth
Must-know: One-layer constraint (copy instead of share), unidirectional flow with TCP/IP stack as the canonical example, benefits (modifiability, reuse, plug-compatible layers) and costs (traversal delay).
⚠️ Top pitfall: Quietly bypassing a layer or keeping 'synchronized copies' — both destroy the independence the pattern buys.
Self-check: Why is copying a module into another layer considered a feature rather than waste?
Connects to: §10.1 Three Ways to Catalog Patterns, §10.5 Allocation Patterns: Multi-Tier and MapReduce, §10.2 A Guided Tour of Component-and-Connector Patterns
The Broker Pattern and Its Proxy
Must-know: Proxy's three jobs: cache, convert, render local services; mail proxy holds mail while offline and pushes when the server returns; clients hand mail over and log out.
⚠️ Top pitfall: Expecting the proxy to remove the broker bottleneck or treating cached answers as permanently fresh.
Self-check: Which proxy duty is exercised when outgoing mail waits in a queue during an outage?
Connects to: §10.2 A Guided Tour of Component-and-Connector Patterns, §10.12 Service-Oriented Architecture in Depth
Pipes and Filters in Depth
Must-know: Compatibility of one module's output with the next's input is the engineering duty; each filter owns its own errors; reordering is justified by bottlenecks and early filtering.
⚠️ Top pitfall: Non-uniform joints or a filter doing two jobs — both kill interchangeability.
Self-check: Why does uniq only work after sort in the classic Unix chain?
Connects to: §10.2 A Guided Tour of Component-and-Connector Patterns, §10.4 The Shared-Data Pattern
Adapter versus Broker
Must-know: Broker = many-to-many at one point (scale); adapter = two incompatible interfaces converted both ways (translation); adapter precondition: each side's needs decodable from the other's output.
⚠️ Top pitfall: Calling any middleman a broker — the many-vs-two test separates them.
Self-check: In the translator story, when would a broker actually be required?
Connects to: §10.2 A Guided Tour of Component-and-Connector Patterns, §10.8 The Broker Pattern and Its Proxy, §10.12 Service-Oriented Architecture in Depth
Model-View-Controller in Depth
Must-know: Roles and arrow law: writes flow view→controller→model, reads go view→model, notifications flow model→subscribed views; dotted diagram lines carry return messages.
⚠️ Top pitfall: Letting views write the model directly or making the model aware of specific views.
Self-check: Which role does the controller play when a user inputs new data on the factory floor?
Connects to: §10.3 The Publisher-Subscriber Pattern, §10.2 A Guided Tour of Component-and-Connector Patterns
Service-Oriented Architecture in Depth
Must-know: Provider/consumer separation through an agreed request format; facade = subsystem-level front class, SOA = whole system offered to external blocks; everything-as-a-service extension.
⚠️ Top pitfall: Using facade and SOA interchangeably, or sharing implementation details instead of contracts.
Self-check: In the Uber example, what exactly does Uber need to know about Google's internals?
Connects to: §10.2 A Guided Tour of Component-and-Connector Patterns, §10.10 Adapter versus Broker
Exam Guidance Summary
Must-know: Answer pattern questions in two moves: name the vanilla pattern, then state its benefits; prepare sequence diagrams by self-study of the supplementary interaction-diagram session.
⚠️ Top pitfall: Overcomplicating answers beyond the vanilla terms the exam uses.
Self-check: What is the flagged item in the assignment guidance?
Connects to: §10.1 Three Ways to Catalog Patterns, §10.6 Using AI Assistants as Study Tools
Key Industry Applications
Must-know: For each named company or technology, recite which pattern it illustrates and the benefit that pattern was bought for.
⚠️ Top pitfall: Memorizing company names without attaching the pattern each one instantiates.
Self-check: Which pattern does the TCP/IP protocol stack illustrate?
Connects to: §10.2 A Guided Tour of Component-and-Connector Patterns, §10.5 Allocation Patterns: Multi-Tier and MapReduce, §10.7 The Layered Pattern in Depth, §10.9 Pipes and Filters in Depth, §10.12 Service-Oriented Architecture in Depth
Was this lecture useful?
BitsNotes AI Assistant
Subject Notes AssistantConfigure AI Chat
Choose how to access the chatbotSigned in as
Powered by BitsNotes — 20 messages per day. No API key needed. Want unlimited access? Use "Bring Your Own Key" mode.
Sign in to use AI Chat
Get 20 free AI messages per day to ask questions about your lecture notes. Sign in with Google or GitHub — it takes 5 seconds.
Sign In to BitsNotesSwitch to "Bring Your Own Key" tab above for unlimited access with any OpenAI-compatible provider.