Observer Pattern: Press Subscribe and Ring the Bell
Master the Observer pattern with a YouTube subscribe and bell icon story, TypeScript and C# event code, real software uses, diagrams and practice tasks.
Press Subscribe, Ring the Bell ๐
Priya is in Class 10 and runs a small YouTube channel called Maths Made Easy. Every Sunday at 6 PM she uploads one new video. Her best friend Arjun loves the channel. Her classmate Meera watches it only before exams. And somewhere on the internet, a playlist robot quietly collects every maths video it can find.
Now think โ how does Arjun come to know a new video is out?
Option one: Arjun opens YouTube every hour and checks Priya's channel page. "New video? No. New video? No. New video? Still no." He checks 30 times on Sunday, and 29 times there is nothing. Wasted time, wasted mobile data, and he still gets the news late. In programming, this wasteful repeated checking is called polling, and it is exactly as silly in code as it is in real life.
Option two โ the smart way: Arjun presses Subscribe and taps the bell icon. Done. Now he can forget about it completely. The moment Priya uploads "Trigonometry in 10 Minutes", YouTube notifies him. His phone buzzes. So does Meera's email. So does the playlist robot. All at once, all automatically.
And here is the beautiful part. Does Priya know Arjun personally? No. Does she keep her subscribers' phone numbers in her diary? No. She just uploads. The channel keeps a subscriber list, and the notification reaches everyone on it. Subscribers can join anytime. They can leave anytime โ Meera will press unsubscribe the day her exams finish, and the buzzing stops for her. Priya's uploading work never changes by even one step.
This is the Observer pattern. The channel is the Subject (also called the Publisher). Arjun, Meera and the robot are the Observers (also called Subscribers). One change on the subject's side โ a new video โ automatically fans out to every observer. Nobody polls. Nobody is hard-wired to anybody.
We will build Priya's channel in code, watch Meera leave gracefully, hunt down a famous memory-leak bug, and learn what many people call the most widely used design pattern in all of software.
What Is the Observer Pattern?
The simple definition:
Observer is a behavioral design pattern that creates a one-to-many relationship between objects. One object โ the Subject โ keeps a list of dependent objects โ the Observers โ and notifies all of them automatically whenever its state changes.
Three small operations make the whole pattern:
- subscribe(observer) โ "Add me to your list." (Pressing the Subscribe button.)
- unsubscribe(observer) โ "Remove me from your list." (Pressing Unsubscribe.)
- notify() โ the subject walks its list and calls each observer's
update()method. (The bell rings on every phone.)
The deep purpose of the pattern is decoupling. The subject does not know the concrete classes of its observers โ it only knows "everyone on my list has an update() method I can call." The observers do not know how the subject works inside โ they only know "I will be called when there is news." Either side can change, grow or shrink without breaking the other.
You will hear other names for the same idea: Event-Subscriber, Listener, or loosely, Publish-Subscribe. (We will see later that strict pub-sub is slightly different โ keep reading.)
Memory trick: Subject = YouTube channel, Observer = subscriber, notify = the bell icon. Subscribe to start receiving, unsubscribe to stop, and the channel never needs to know who you are. If you remember the bell, you remember the pattern.
The Problem It Solves: The Hard-Wired Channel
Let us feel the pain first. Imagine YouTube was badly programmed, and the channel had to personally inform each viewer type, by name, in its own code:
// โ BAD: the channel is hard-wired to every concrete viewer
class Channel {
uploadVideo(title: string) {
console.log(`Uploaded: ${title}`);
// The channel must personally know and call EVERY interested party:
arjunsPhone.showNotification(title);
meerasEmail.sendMail(title);
schoolNoticeBoard.pinPoster(title);
statisticsPanel.increaseCount(title);
// Tomorrow a smartwatch app comes? EDIT THIS FILE AGAIN!
}
}What is wrong with this?
- The channel depends on every concrete receiver. Phone, email, notice board, statistics โ the channel's code must import and know all of them. Adding a new receiver means editing the channel. This breaks the Open/Closed Principle (open for extension, closed for modification).
- No runtime control. Meera cannot unsubscribe after her exams. The wiring is fixed in code, not in data. To stop her notifications, someone must edit and re-deploy the channel!
- The channel does two jobs. Its real job is managing videos. Now it also maintains a registry of receivers. Two responsibilities in one class โ a known design smell.
- The only alternative is polling. If the channel notifies nobody, every viewer must repeatedly ask, "Anything new? Anything new?" โ wasted work and late news, like Arjun refreshing 30 times.
Look at the difference in shape:
With the observer pattern, the channel knows only one thing: "I have a list, and everyone on it understands update()." Whether the list holds two observers or two million, whether they are phones or smartwatches or things not invented yet โ the channel's code never changes.
This is the same difference as a school notice board versus personally informing each student. The principal pins one notice; whoever has "subscribed" (walks past the board) gets the news. The principal does not visit 800 classrooms.
When Priya uploads one video today, who actually reacts? More parties than you would guess:
Each slice is a different observer family, and Priya's upload button knows none of them by name. That is the whole point.
How It Works, Step by Step
The recipe:
- Identify the subject and the observers. The subject is the thing that changes (channel, weather station, stock price). The observers are the things that react (displays, loggers, notification senders).
- Declare the Observer interface. Usually one method:
update(...). Decide what data it receives (push vs pull โ see below). - Give the subject the three operations.
subscribe,unsubscribe, andnotify, plus an internal list of observers. - Call
notify()whenever the state changes โ and only after the state is fully updated, so observers reading back see consistent values. - Implement concrete observers. Each reacts in its own way to the same news.
- Wire and clean up. Client code subscribes the observers. And โ very important โ unsubscribes them when they are no longer needed. We will see why in blood-curdling detail soon.
Here is the moment Priya uploads, as a message-by-message sequence:
And the same Sunday from the humans' side:
Compare Arjun's flat row of 5s with his polling life from the introduction. Subscribe once, then live your life. The pattern's gift to observers is freedom from checking.
Push or Pull? ๐จ
One design choice matters here: how much information travels in update()?
- Push model: the subject sends the data itself โ
update("Trigonometry in 10 Minutes"). Quick and simple, but the subject must guess what every observer needs, and it pushes the same packet to all. - Pull model: the subject sends only itself โ
update(channel)โ and each observer asks the channel for whatever it wants:channel.latestVideo(),channel.subscriberCount(). Flexible, but observers must know the subject's API, which couples them a little tighter. - Practical middle path: pass a small, immutable event object carrying the useful facts. This is exactly how C#
EventArgsand DOMEventobjects work.
| Question | Push model | Pull model | Event object (middle path) |
|---|---|---|---|
| Who decides what data flows? | Subject | Each observer | Subject, but in a structured packet |
| Coupling | Lowest for observers | Observers must know subject API | Low โ only the event type is shared |
| Risk | Sends data some observers ignore | Observer may read mid-change state | Slightly more classes to write |
| Real example | update(title) | update(this) then channel.latestVideo() | DOM Event, C# EventArgs |
College corner: push versus pull is really a question about who pays the cost of generality. Pure push is O(1) calls per observer but forces the subject to precompute a one-size-fits-all payload; pure pull lets each observer fetch exactly what it needs but turns one notification into k extra subject reads, and risks reading state that changed after the notification was queued (a consistency hazard in async systems). The GoF book notes that pull is more reusable and push is more efficient. Production frameworks almost universally pick the immutable event-object compromise: one allocation, consistent data frozen at notify time, no callback into the subject.
The Blueprint ๐
The class structure to memorise โ interfaces on both sides, concrete classes meeting only through them:
One arrow deserves a long stare: Subject --> Observer points at the interface. There is no arrow from YouTubeChannel to PhoneNotification. The channel will happily notify observer types that have not been invented yet.
An observer also lives a small life of states โ and one of those states is a trap:
Hold that Zombie state in your mind. We will meet it again, with numbers.
Real Code: Priya's Channel in TypeScript
Let us build Maths Made Easy โ with subscribe, notify and unsubscribe, the full trio.
// --- The Observer interface: anyone who wants the bell to ring ---
interface Subscriber {
readonly name: string;
update(channelName: string, videoTitle: string): void; // push model
}
// --- The Subject: Priya's channel ---
class YouTubeChannel {
private subscribers: Subscriber[] = [];
private videos: string[] = [];
constructor(public readonly name: string) {}
// ๐ "Press subscribe"
subscribe(s: Subscriber): void {
if (!this.subscribers.includes(s)) {
this.subscribers.push(s);
console.log(`${s.name} subscribed to ${this.name}. ๐`);
}
}
// ๐ "Press unsubscribe"
unsubscribe(s: Subscriber): void {
this.subscribers = this.subscribers.filter((sub) => sub !== s);
console.log(`${s.name} unsubscribed from ${this.name}. ๐`);
}
// Priya's real work โ and the trigger for notifications
uploadVideo(title: string): void {
this.videos.push(title);
console.log(`\n${this.name} uploaded: "${title}"`);
this.notify(title);
}
// Walk the list and ring every bell.
// We loop over a COPY, so an observer may safely
// unsubscribe itself while being notified.
private notify(title: string): void {
for (const s of [...this.subscribers]) {
s.update(this.name, title);
}
}
}
// --- Concrete observers: each reacts in its own way ---
class PhoneNotification implements Subscriber {
constructor(public readonly name: string) {}
update(channel: string, title: string): void {
console.log(` ๐ฑ ${this.name}'s phone buzzes: New on ${channel} โ "${title}"`);
}
}
class EmailDigest implements Subscriber {
constructor(public readonly name: string) {}
update(channel: string, title: string): void {
console.log(` โ๏ธ Email queued for ${this.name}: ${channel} released "${title}"`);
}
}
class WatchLaterList implements Subscriber {
readonly name = "Watch-Later Bot";
private list: string[] = [];
update(_channel: string, title: string): void {
this.list.push(title);
console.log(` ๐ค Watch-Later Bot saved "${title}" (total: ${this.list.length})`);
}
}
// --- The story runs ---
const channel = new YouTubeChannel("Maths Made Easy");
const arjun = new PhoneNotification("Arjun");
const meera = new EmailDigest("Meera");
const bot = new WatchLaterList();
channel.subscribe(arjun); // Arjun presses the bell
channel.subscribe(meera); // Meera prefers email
channel.subscribe(bot); // a bot subscribes too โ the channel doesn't care!
channel.uploadVideo("Trigonometry in 10 Minutes");
channel.unsubscribe(meera); // exams over, Meera unsubscribes
channel.uploadVideo("Algebra Tricks for Class 7");The output:
Arjun subscribed to Maths Made Easy. ๐
Meera subscribed to Maths Made Easy. ๐
Watch-Later Bot subscribed to Maths Made Easy. ๐
Maths Made Easy uploaded: "Trigonometry in 10 Minutes"
๐ฑ Arjun's phone buzzes: New on Maths Made Easy โ "Trigonometry in 10 Minutes"
โ๏ธ Email queued for Meera: Maths Made Easy released "Trigonometry in 10 Minutes"
๐ค Watch-Later Bot saved "Trigonometry in 10 Minutes" (total: 1)
Meera unsubscribed from Maths Made Easy. ๐
Maths Made Easy uploaded: "Algebra Tricks for Class 7"
๐ฑ Arjun's phone buzzes: New on Maths Made Easy โ "Algebra Tricks for Class 7"
๐ค Watch-Later Bot saved "Algebra Tricks for Class 7" (total: 2)Notice the three wins:
YouTubeChannelnever mentionsPhoneNotification,EmailDigestor any concrete class. It knows only theSubscriberinterface. We added a bot without touching the channel.- Meera unsubscribed at runtime โ no code edit, no re-deploy. The next notify simply skipped her.
notify()loops over a copy of the list, so an observer can even unsubscribe itself during a notification without breaking the loop.
The Same Idea in C# โ Events Built Into the Language
C# loved this pattern so much that it built it into the language as events. The event keyword gives you the subscriber list, subscribe (+=), unsubscribe (-=), and notify (invoking the event) for free:
using System;
// The event data โ a small immutable packet (the practical push model)
public class VideoUploadedEventArgs : EventArgs
{
public string Title { get; }
public VideoUploadedEventArgs(string title) => Title = title;
}
// --- The Subject ---
public class YouTubeChannel
{
public string Name { get; }
public YouTubeChannel(string name) => Name = name;
// This ONE line replaces our whole subscribe/unsubscribe/notify machinery!
public event EventHandler<VideoUploadedEventArgs>? VideoUploaded;
public void UploadVideo(string title)
{
Console.WriteLine($"\n{Name} uploaded: \"{title}\"");
// notify(): invoke the event; C# calls every handler on the list
VideoUploaded?.Invoke(this, new VideoUploadedEventArgs(title));
}
}
// --- The story ---
public static class Program
{
public static void Main()
{
var channel = new YouTubeChannel("Maths Made Easy");
// subscribe with += (press the bell)
EventHandler<VideoUploadedEventArgs> arjunsPhone =
(sender, e) => Console.WriteLine($" ๐ฑ Arjun's phone: \"{e.Title}\" is out!");
EventHandler<VideoUploadedEventArgs> meerasEmail =
(sender, e) => Console.WriteLine($" โ๏ธ Email for Meera: \"{e.Title}\"");
channel.VideoUploaded += arjunsPhone;
channel.VideoUploaded += meerasEmail;
channel.UploadVideo("Trigonometry in 10 Minutes"); // both react
channel.VideoUploaded -= meerasEmail; // unsubscribe with -=
channel.UploadVideo("Algebra Tricks for Class 7"); // only Arjun reacts
}
}Every C# event you have ever used โ every button.Click += ... โ is the Observer pattern wearing language-level clothes. Java has listener interfaces, JavaScript has addEventListener, Python has signal libraries. The pattern is so useful that languages absorbed it.
And in Python, ten lines capture the soul of it:
class Channel:
def __init__(self, name):
self.name = name
self.subscribers = [] # the list IS the pattern
def subscribe(self, fn):
self.subscribers.append(fn)
def unsubscribe(self, fn):
self.subscribers.remove(fn)
def upload(self, title):
print(f"{self.name} uploaded: {title}")
for fn in list(self.subscribers): # copy, same trick as TypeScript
fn(title)
channel = Channel("Maths Made Easy")
arjun = lambda t: print(f" Arjun's phone buzzes: {t}")
channel.subscribe(arjun)
channel.upload("Trigonometry in 10 Minutes")
channel.unsubscribe(arjun) # always pair subscribe with unsubscribe!
channel.upload("Algebra Tricks") # silence โ Arjun has moved onThe Zombie Listener Hunt ๐ง
Now the promised horror story, with numbers. It is the most expensive Observer bug in real applications, and it has an official name: the lapsed listener problem.
Picture a mobile app. There is one long-lived subject โ a global event bus that lives as long as the app. And there are short-lived observers โ screens the user opens and closes. Each screen subscribes when it opens. And the programmer forgets to unsubscribe when it closes.
The subject's list now holds a strong reference to every dead screen. The garbage collector looks at each one and says, "Someone still points at this โ I cannot delete it." Open and close that screen 300 times, and 300 zombie screens sit in memory, each still receiving and processing every notification. The app gets slower and fatter until it crashes.
Watch the two destinies diverge:
The top line is the forgetful app โ straight to a crash. The bottom line is the disciplined app: every subscribe paired with an unsubscribe, so at any moment only the currently open screen is listening. Same features, same pattern, one missing line of cleanup between them.
College corner: the leak happens because a subscription reverses the expected ownership direction. Normally short-lived objects reference long-lived ones and die freely. Subscribing makes the long-lived subject hold a strong reference to the short-lived observer โ so the observer's lifetime silently becomes the subject's lifetime. Three industrial cures: (1) deterministic cleanup hooks โ IDisposable in C#, the cleanup function returned from React's useEffect, Angular's takeUntilDestroyed; (2) weak references โ Java's WeakReference, C# weak event patterns โ which let the GC collect observers the list still points to, at the cost of unpredictable delivery; (3) subscription objects โ RxJS returns a Subscription whose unsubscribe() you store and call, making the cleanup an explicit, ownable value. Also know the time cost: notify() is O(n) synchronous calls on the subject's thread, so a thousand zombies do not just waste memory โ they slow every single upload.
Should You Use It Here?
And the scan-in-ten-seconds table:
| Situation | Use Observer? | Why |
|---|---|---|
| One change must reach many reactors, count unknown in advance | โ Yes | The subscriber list handles any number |
| Listeners must come and go at runtime | โ Yes | subscribe/unsubscribe are cheap |
| You want to avoid polling ("anything new yet?") | โ Yes | The subject pushes when news actually happens |
| The subject must not depend on concrete reactor classes | โ Yes | It sees only the Observer interface |
| Exactly one fixed receiver, forever | โ No | A direct method call is simpler and clearer |
| Observers must run in a strict, guaranteed order | โ Careful | Plain Observer gives weak ordering promises |
| All observers must succeed together or not at all (transactions) | โ No | Partial failure is normal in Observer; you need different machinery |
Where You See It in Real Software
The Observer pattern may be the single most-used pattern in real code:
- DOM event listeners. Every
button.addEventListener("click", handler)in the browser subscribes an observer to a subject;removeEventListenerunsubscribes. Since 2017, browsers even expose a constructableEventTargetso your own objects can be subjects, as described on patterns.dev. - React and state management. When state changes, the components depending on it are notified and re-render. Libraries like Redux let components subscribe to a store; one dispatch fans out to all connected components. The cleanup function in
useEffectexists precisely to kill zombie listeners. - RxJS and Angular. RxJS is a whole library built around observables โ observer pattern with superpowers like merging streams, debouncing a search box and retrying on failure. Angular ships with it.
- MQTT and message brokers. IoT devices publish to topics; subscribers receive selected messages through a broker. This is the broker-style pub-sub big brother of Observer, used for chat apps, live cricket score updates and GPS tracking feeds.
- Newsletters and notification systems. Email lists, push-notification services and the literal YouTube bell are observer lists at internet scale.
- Open-source examples. The java-design-patterns repository has a runnable example, and Refactoring Guru shows it in ten languages.
Common Mistakes Students Make โ ๏ธ
Mistake 1: Forgetting to unsubscribe โ the memory leak that haunts real apps. This is the zombie story of Figure 7 in one paragraph. A long-lived subject keeps a strong reference to every observer on its list. If a short-lived observer (a closed screen, a finished task) never unsubscribes, the garbage collector can never free it. It stays in memory, still receiving and processing every notification, forever. Open a screen 500 times and 500 zombies are listening. The cures: always pair every subscribe with an unsubscribe (in dispose, in useEffect cleanup, via IDisposable), or use weak references where the language supports them. Repeat the rule aloud: no subscribe without a planned unsubscribe.
Mistake 2: Notifying before the state is ready. If you call notify() halfway through updating the subject, observers that pull data will read a half-updated, inconsistent state โ a video title with no video behind it. Always finish updating first; ring the bell last.
A few more to watch:
- Modifying the list during notification without a snapshot copy โ you can skip observers or crash the loop. Notify over
[...subscribers], like our code does. - Letting one bad observer kill the rest. If observer #2 throws an exception, observers #3 to #10 may never hear the news. Wrap each call in try/catch if observers are untrusted.
- Update storms and loops. Observer A's update changes a subject that B observes, B's update changes a subject A observes... infinite ping-pong until the stack overflows. Keep update handlers small and avoid writing to other subjects inside them.
Compare With the Cousins
The two comparisons every student must master: Observer vs Pub-Sub, and Observer vs Mediator.
| Question | Observer (classic) | Publish-Subscribe (broker style) | Mediator |
|---|---|---|---|
| Who is in the middle? | Nobody โ subject holds the list directly | A broker / event bus / topic channel | A mediator that owns coordination logic |
| Do the two sides know each other? | Through an interface, yes (direct wiring) | Not at all โ only the topic name | Components know only the mediator |
| Same process? | Usually yes, same call stack | Often different processes or machines | Yes |
| Delivery | Synchronous, immediate | Often asynchronous, queued | Mediator decides |
| Direction | One-way broadcast | One-way through topics | Two-way conversations |
| Real-life picture | Channel calls its own subscriber list | Post office sorting letters by address | Air traffic control tower |
The nuance in one sentence: every pub-sub is observer-like, but classic Observer is broker-less โ the subject itself keeps the list and rings the bells. The moment a middleman with topics appears, and publishers and subscribers stop sharing any reference, you have crossed into true pub-sub (MQTT, Kafka, an event bus). The Design Gurus comparison explains this line well.
And versus Mediator: Observer says "fan one change out to many listeners." Mediator says "centralize many-to-many conversations in one brain." Interestingly, a mediator is often implemented using observer underneath โ the tower subscribes to events from its planes.
The Whole Pattern in One Picture ๐บ๏ธ
Quick Revision Box
+--------------------------------------------------------------+
| OBSERVER โ QUICK REVISION |
+--------------------------------------------------------------+
| What : One Subject notifies MANY Observers |
| automatically when its state changes. |
| Picture : YouTube channel + Subscribe button + bell icon. |
| Trio : subscribe(o), unsubscribe(o), notify() |
| Models : Push = send the data; Pull = send yourself, |
| observer asks back; Middle = small event object. |
| Wins : No polling, loose coupling, listeners join and |
| leave at runtime, Open/Closed friendly. |
| Danger #1: FORGOTTEN UNSUBSCRIBE = memory leak |
| (the lapsed listener problem). Always clean up! |
| Dangers : notify before state ready, update storms, |
| one failing observer blocking the rest. |
| Cousins : Pub-Sub = adds a broker + topics (async, remote); |
| Mediator = two-way coordination brain. |
| Used in : addEventListener, C# events, React/Redux, RxJS, |
| MQTT, push notifications. |
+--------------------------------------------------------------+Practice Exercises โ๏ธ
Try these yourself. Start from the TypeScript channel code above.
-
Cricket score updates. Build a
CricketMatchsubject that holds the score. Observers:MobileApp(shows "IND 245/3"),StadiumScreen(shows big text), andCommentator(prints an excited sentence on every boundary). Callmatch.updateScore(runs, wickets)a few times. Then unsubscribeCommentatorduring the innings break and confirm the silence. -
The leak hunt. Take your solution from task 1. Create and subscribe 1,000
MobileAppobservers in a loop, but "forget" to unsubscribe them, and keep only the last one in a variable. Add a counter that prints how many observers were notified on each update. Watch the number stay at 1,000 โ those are your zombie listeners from Figure 7! Now fix it: unsubscribe each app before creating the next, and watch the counter behave. Write one sentence on why this matters more in a long-running app than in a small script. -
Push to pull. Convert the
YouTubeChannelfrom push to pull:update()should receive the channel itself, and each observer should callchannel.latestVideo(). Then write two sentences comparing the coupling in both versions. Which observers became more powerful, and what new risk did they take on? -
School notice board (challenge). Model a
NoticeBoardsubject with topics: "sports", "exams", "holidays". Students subscribe only to topics they care about, likeboard.subscribe("exams", ravi). When the principal posts a notice to a topic, only that topic's subscribers are notified. Question to think about: by adding topics and a middleman board, which pattern have you started moving towards โ classic Observer, or Publish-Subscribe? Explain in two sentences. -
Weak bell (college). Research your language's weak reference tool (
WeakRefin JavaScript,WeakReferencein Java/C#). Rewrite the subscriber list to hold weak references, so zombie listeners can be garbage collected even without unsubscribing. Then write three sentences on the new problem you introduced: when exactly can a live observer silently miss a notification?
Frequently asked questions
- What is the Observer pattern in one line?
- It is a behavioral design pattern where one object (the subject) keeps a list of interested objects (observers) and automatically notifies all of them whenever its state changes โ like a YouTube channel notifying its subscribers.
- What is the difference between Observer and Publish-Subscribe?
- In classic Observer, the subject holds a direct list of its observers and calls them itself. In true Pub-Sub, a middleman (broker or event bus) sits between publishers and subscribers, so they never know each other and may even run on different machines.
- Why must observers unsubscribe?
- If a long-lived subject keeps a strong reference to an observer that is no longer needed, the garbage collector can never free that observer. This 'lapsed listener' problem is one of the most common causes of memory leaks.
- What is the push model vs the pull model?
- In push, the subject sends the changed data as arguments to update(). In pull, the subject sends only a notification and each observer asks the subject for the data it needs. Many real systems mix both by passing a small event object.
- Where do I see the Observer pattern in everyday code?
- DOM addEventListener in browsers, C# events, React re-rendering on state change, RxJS observables, and notification systems like the YouTube bell all follow the observer idea.
Further reading
Related Lessons
Mediator Pattern: The Control Tower That Stops the Chaos
Learn the Mediator pattern with an airport control tower story, simple TypeScript and C# code, MediatR examples, diagrams, tables and easy practice tasks.
Command Pattern: Turn Every Action into an Order Slip
Learn the Command pattern through a restaurant order slip story. Simple TypeScript and C# code with undo and redo, diagrams, tables, and practice tasks.
Chain of Responsibility Pattern: Pass the Request Until Someone Handles It
Learn the Chain of Responsibility pattern with a simple school leave application story, easy TypeScript and C# code, diagrams, tables, and practice tasks.
Memento Pattern: Save Your Game Before the Boss Fight
Understand the Memento pattern through a video game save point story, with TypeScript and Python undo examples, diagrams, tables and easy practice tasks.