Skip to content

Commit 1414ffb

Browse files
Observer Pattern Blog Added
1 parent ff2855e commit 1414ffb

File tree

11 files changed

+671
-10
lines changed

11 files changed

+671
-10
lines changed
35.7 KB
Loading

content/Observer Pattern.md

Lines changed: 221 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,221 @@
1-
<marquee>Comming Soon</marquee>
1+
#behavioral
2+
## Definition
3+
4+
It Defines a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically. Just like the Subscription, as long as you take the subscription you will get the updates, when you invoke the Subscription you will stop getting the updates or say the services.
5+
6+
---
7+
## Real World Analogy
8+
9+
We are designing a **Weather Application** that consists of a `WeatherData` class. There are different types of displays attached to it, but currently, we only have `CurrentConditionsDisplay`.
10+
When the data inside the `WeatherData` class changes (i.e., **temperature, pressure, and humidity**), the updated data should be reflected on the display as well.
11+
The application should be designed in such a way that when a new display is added, we **don’t need to rewrite or modify** the existing code.
12+
The **Observer Pattern** is the ideal solution here. When the `WeatherData` class updates, it acts as a **Subject**, and its dependents (Observers/Subscribers) are notified automatically—**as long as they are registered with the Subject**.
13+
14+
![[Pasted image 20250212000000.png]]
15+
_Publisher Notifies all the Subscriber_
16+
### Design
17+
```mermaid
18+
---
19+
title: Observer Pattern
20+
---
21+
classDiagram
22+
direction TB
23+
24+
class Subject {
25+
<<interface>>
26+
+registerObserver(o: Observer)
27+
+removeObserver(o: Observer)
28+
+notifyObserver()
29+
}
30+
31+
class Observer {
32+
<<interface>>
33+
+update()
34+
}
35+
36+
class DisplayElement {
37+
<<interface>>
38+
+display()
39+
}
40+
41+
class WeatherData {
42+
- List<Observer> observers
43+
- float temperature
44+
- float humidity
45+
- float pressure
46+
+registerObserver(o: Observer)
47+
+removeObserver(o: Observer)
48+
+notifyObserver()
49+
+measurementsChanged()
50+
+setMeasurements(temperature: float, pressure: float, humidity: float)
51+
+getTemperature(): float
52+
+getHumidity(): float
53+
+getPressure(): float
54+
}
55+
56+
class CurrentConditionDisplay {
57+
- WeatherData weatherdata
58+
+CurrentConditionDisplay(weatherdata: WeatherData)
59+
+display()
60+
+update()
61+
}
62+
63+
class ForecastDisplay {
64+
- WeatherData weatherdata
65+
+ForecastDisplay(weatherdata: WeatherData)
66+
+display()
67+
+update()
68+
}
69+
70+
Subject <|.. WeatherData
71+
Observer <|.. CurrentConditionDisplay
72+
Observer <|.. ForecastDisplay
73+
DisplayElement <|.. CurrentConditionDisplay
74+
DisplayElement <|.. ForecastDisplay
75+
76+
WeatherData --> Observer : "maintains a list of"
77+
WeatherData --> CurrentConditionDisplay : "registers Observer"
78+
WeatherData --> ForecastDisplay : "registers Observer"
79+
80+
```
81+
The Design will look like the Above.
82+
83+
---
84+
### Code in Java
85+
```java title:Observerpattern.java
86+
// These is the Subject
87+
interface Subject {
88+
public void registerObserver(Observer o);
89+
public void removeObserver(Observer o);
90+
public void notifyObserver();
91+
}
92+
93+
interface Observer {
94+
public void update();
95+
}
96+
97+
interface DisplayElement {
98+
public void display();
99+
}
100+
101+
// These is the main subject the observer register here to receive the updates to all the subscribed observer.
102+
class WeatherData implements Subject {
103+
104+
private List<Observer> observers = new ArrayList<Observer>();
105+
private float temperature = 0;
106+
private float humidity = 0;
107+
private float pressure = 0;
108+
109+
// Register the Observer
110+
@Override
111+
public void registerObserver(Observer o) {
112+
observers.add(o);
113+
}
114+
115+
@Override
116+
public void removeObserver(Observer o) {
117+
observers.remove(o);
118+
}
119+
120+
// Notify all the observer which are subscribed
121+
@Override
122+
public void notifyObserver() {
123+
for (Observer obs : observers) {
124+
obs.update();
125+
}
126+
}
127+
128+
// when the measurements are changed notify's all the subscriber
129+
public void measurementsChanged() {
130+
this.notifyObserver();
131+
}
132+
133+
// Sets the measurements and displays the updates.
134+
public void setMeasurements(float temperature, float pressure, float humidity) {
135+
this.humidity = humidity;
136+
this.pressure = pressure;
137+
this.temperature = temperature;
138+
this.measurementsChanged();
139+
}
140+
141+
public float getTemperature() {
142+
return temperature;
143+
}
144+
145+
public float getHumidity() {
146+
return humidity;
147+
}
148+
149+
public float getPressure() {
150+
return pressure;
151+
}
152+
153+
}
154+
155+
// There can be multiple displays developer can add as many display as it wants by using DisplayElement Interface
156+
class CurrentConditionDisplay implements Observer, DisplayElement {
157+
private WeatherData weatherdata;
158+
159+
public CurrentConditionDisplay(WeatherData weatherdata) {
160+
this.weatherdata = weatherdata;
161+
this.weatherdata.registerObserver(this);
162+
}
163+
164+
@Override
165+
public void display() {
166+
System.out.println("Current Condition = " + weatherdata.getHumidity() + " " + weatherdata.getPressure());
167+
}
168+
169+
@Override
170+
public void update() {
171+
this.display();
172+
}
173+
174+
}
175+
176+
// lets add new display again
177+
class ForecastDisplay implements DisplayElement, Observer {
178+
private WeatherData weatherdata;
179+
180+
public ForecastDisplay(WeatherData weatherdata) {
181+
this.weatherdata = weatherdata;
182+
this.weatherdata.registerObserver(this);
183+
}
184+
185+
@Override
186+
public void display() {
187+
System.out.println("Forecast Display = " + weatherdata.getHumidity() * 100 + " " + weatherdata.getPressure());
188+
}
189+
190+
@Override
191+
public void update() {
192+
this.display();
193+
}
194+
195+
}
196+
197+
public class ObserverPattern {
198+
199+
public static void main(String[] args) {
200+
// Creating the instance of Weather Class
201+
WeatherData weatherdata = new WeatherData();
202+
203+
// Displaying the data from the Weather Data using Observer or Display
204+
CurrentConditionDisplay currcondition = new CurrentConditionDisplay(weatherdata);
205+
ForecastDisplay forecastdisplay = new ForecastDisplay(weatherdata);
206+
207+
// Setting the measurements in the weather data
208+
weatherdata.setMeasurements(1, 1, 2);
209+
weatherdata.setMeasurements(5, 5, 5);
210+
}
211+
}
212+
```
213+
**Output:**
214+
```
215+
Current Condition = 2.0 1.0
216+
Forecast Display = 200.0 1.0
217+
Current Condition = 5.0 5.0
218+
Forecast Display = 500.0 5.0
219+
```
220+
---
221+
## Real World Example

content/Strategy Pattern.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,17 @@ public class Index {
212212
}
213213
}
214214
```
215+
**Output:**
216+
```
217+
======= Rubber Duck ======
218+
Can't Fly
219+
MUte Quacking
220+
221+
===== Mallard Duck =====
222+
Can Fly
223+
Squeak
224+
```
225+
215226
---
216227
## Real World Analogy - 2
217228

@@ -264,3 +275,35 @@ classDiagram
264275
265276
```
266277
---
278+
## Real World Example
279+
280+
The `Comparator` interface acts as the Strategy Pattern. By inheriting this interface, you can create your custom comparator, which allows you to sort collections.
281+
282+
```java title:Person.java
283+
class NameComparator implements Comparator<Person> {
284+
public int compare(Person p1, Person p2) {
285+
return p1.name.compareTo(p2.name);
286+
}
287+
}
288+
289+
List<Person> people = Arrays.asList(
290+
new Person("Alice", 25),
291+
new Person("Bob", 30),
292+
new Person("Charlie", 22)
293+
);
294+
295+
// Apply sorting strategy at runtime
296+
Collections.sort(people, new NameComparator());
297+
System.out.println("Sorted by name: " + people);
298+
```
299+
---
300+
## Design Principles
301+
302+
> [!Note] Note
303+
> The Design Principles will be changing based on the Design Patterns and new design principles will be added to it as you go through the Different Design Patterns.
304+
305+
- **Encapsulate What Varies** - Identify the parts of the code that are going to change and encapsulate them into separate class just like the Strategy Pattern.
306+
- **Favor Composition Over Inheritance** - Instead of using inheritance on extending functionality, rather use composition by delegating behavior to other objects.
307+
- **Program to Interface not Implementations** - Write code that depends on Abstractions or Interfaces rather than Concrete Classes.
308+
---
309+
35.7 KB
Loading

0 commit comments

Comments
 (0)