-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ff2855e
commit 1414ffb
Showing
11 changed files
with
671 additions
and
10 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,221 @@ | ||
<marquee>Comming Soon</marquee> | ||
#behavioral | ||
## Definition | ||
|
||
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. | ||
|
||
--- | ||
## Real World Analogy | ||
|
||
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`. | ||
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. | ||
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. | ||
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**. | ||
|
||
![[Pasted image 20250212000000.png]] | ||
_Publisher Notifies all the Subscriber_ | ||
### Design | ||
```mermaid | ||
--- | ||
title: Observer Pattern | ||
--- | ||
classDiagram | ||
direction TB | ||
class Subject { | ||
<<interface>> | ||
+registerObserver(o: Observer) | ||
+removeObserver(o: Observer) | ||
+notifyObserver() | ||
} | ||
class Observer { | ||
<<interface>> | ||
+update() | ||
} | ||
class DisplayElement { | ||
<<interface>> | ||
+display() | ||
} | ||
class WeatherData { | ||
- List<Observer> observers | ||
- float temperature | ||
- float humidity | ||
- float pressure | ||
+registerObserver(o: Observer) | ||
+removeObserver(o: Observer) | ||
+notifyObserver() | ||
+measurementsChanged() | ||
+setMeasurements(temperature: float, pressure: float, humidity: float) | ||
+getTemperature(): float | ||
+getHumidity(): float | ||
+getPressure(): float | ||
} | ||
class CurrentConditionDisplay { | ||
- WeatherData weatherdata | ||
+CurrentConditionDisplay(weatherdata: WeatherData) | ||
+display() | ||
+update() | ||
} | ||
class ForecastDisplay { | ||
- WeatherData weatherdata | ||
+ForecastDisplay(weatherdata: WeatherData) | ||
+display() | ||
+update() | ||
} | ||
Subject <|.. WeatherData | ||
Observer <|.. CurrentConditionDisplay | ||
Observer <|.. ForecastDisplay | ||
DisplayElement <|.. CurrentConditionDisplay | ||
DisplayElement <|.. ForecastDisplay | ||
WeatherData --> Observer : "maintains a list of" | ||
WeatherData --> CurrentConditionDisplay : "registers Observer" | ||
WeatherData --> ForecastDisplay : "registers Observer" | ||
``` | ||
The Design will look like the Above. | ||
|
||
--- | ||
### Code in Java | ||
```java title:Observerpattern.java | ||
// These is the Subject | ||
interface Subject { | ||
public void registerObserver(Observer o); | ||
public void removeObserver(Observer o); | ||
public void notifyObserver(); | ||
} | ||
|
||
interface Observer { | ||
public void update(); | ||
} | ||
|
||
interface DisplayElement { | ||
public void display(); | ||
} | ||
|
||
// These is the main subject the observer register here to receive the updates to all the subscribed observer. | ||
class WeatherData implements Subject { | ||
|
||
private List<Observer> observers = new ArrayList<Observer>(); | ||
private float temperature = 0; | ||
private float humidity = 0; | ||
private float pressure = 0; | ||
|
||
// Register the Observer | ||
@Override | ||
public void registerObserver(Observer o) { | ||
observers.add(o); | ||
} | ||
|
||
@Override | ||
public void removeObserver(Observer o) { | ||
observers.remove(o); | ||
} | ||
|
||
// Notify all the observer which are subscribed | ||
@Override | ||
public void notifyObserver() { | ||
for (Observer obs : observers) { | ||
obs.update(); | ||
} | ||
} | ||
|
||
// when the measurements are changed notify's all the subscriber | ||
public void measurementsChanged() { | ||
this.notifyObserver(); | ||
} | ||
|
||
// Sets the measurements and displays the updates. | ||
public void setMeasurements(float temperature, float pressure, float humidity) { | ||
this.humidity = humidity; | ||
this.pressure = pressure; | ||
this.temperature = temperature; | ||
this.measurementsChanged(); | ||
} | ||
|
||
public float getTemperature() { | ||
return temperature; | ||
} | ||
|
||
public float getHumidity() { | ||
return humidity; | ||
} | ||
|
||
public float getPressure() { | ||
return pressure; | ||
} | ||
|
||
} | ||
|
||
// There can be multiple displays developer can add as many display as it wants by using DisplayElement Interface | ||
class CurrentConditionDisplay implements Observer, DisplayElement { | ||
private WeatherData weatherdata; | ||
|
||
public CurrentConditionDisplay(WeatherData weatherdata) { | ||
this.weatherdata = weatherdata; | ||
this.weatherdata.registerObserver(this); | ||
} | ||
|
||
@Override | ||
public void display() { | ||
System.out.println("Current Condition = " + weatherdata.getHumidity() + " " + weatherdata.getPressure()); | ||
} | ||
|
||
@Override | ||
public void update() { | ||
this.display(); | ||
} | ||
|
||
} | ||
|
||
// lets add new display again | ||
class ForecastDisplay implements DisplayElement, Observer { | ||
private WeatherData weatherdata; | ||
|
||
public ForecastDisplay(WeatherData weatherdata) { | ||
this.weatherdata = weatherdata; | ||
this.weatherdata.registerObserver(this); | ||
} | ||
|
||
@Override | ||
public void display() { | ||
System.out.println("Forecast Display = " + weatherdata.getHumidity() * 100 + " " + weatherdata.getPressure()); | ||
} | ||
|
||
@Override | ||
public void update() { | ||
this.display(); | ||
} | ||
|
||
} | ||
|
||
public class ObserverPattern { | ||
|
||
public static void main(String[] args) { | ||
// Creating the instance of Weather Class | ||
WeatherData weatherdata = new WeatherData(); | ||
|
||
// Displaying the data from the Weather Data using Observer or Display | ||
CurrentConditionDisplay currcondition = new CurrentConditionDisplay(weatherdata); | ||
ForecastDisplay forecastdisplay = new ForecastDisplay(weatherdata); | ||
|
||
// Setting the measurements in the weather data | ||
weatherdata.setMeasurements(1, 1, 2); | ||
weatherdata.setMeasurements(5, 5, 5); | ||
} | ||
} | ||
``` | ||
**Output:** | ||
``` | ||
Current Condition = 2.0 1.0 | ||
Forecast Display = 200.0 1.0 | ||
Current Condition = 5.0 5.0 | ||
Forecast Display = 500.0 5.0 | ||
``` | ||
--- | ||
## Real World Example |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.