Skip to content

Commit

Permalink
Observer Pattern Blog Added
Browse files Browse the repository at this point in the history
  • Loading branch information
PrathameshDhande22 committed Feb 11, 2025
1 parent ff2855e commit 1414ffb
Show file tree
Hide file tree
Showing 11 changed files with 671 additions and 10 deletions.
Binary file added content/Images/Pasted image 20250212000000.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
222 changes: 221 additions & 1 deletion content/Observer Pattern.md
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
43 changes: 43 additions & 0 deletions content/Strategy Pattern.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,17 @@ public class Index {
}
}
```
**Output:**
```
======= Rubber Duck ======
Can't Fly
MUte Quacking
===== Mallard Duck =====
Can Fly
Squeak
```

---
## Real World Analogy - 2

Expand Down Expand Up @@ -264,3 +275,35 @@ classDiagram
```
---
## Real World Example

The `Comparator` interface acts as the Strategy Pattern. By inheriting this interface, you can create your custom comparator, which allows you to sort collections.

```java title:Person.java
class NameComparator implements Comparator<Person> {
public int compare(Person p1, Person p2) {
return p1.name.compareTo(p2.name);
}
}

List<Person> people = Arrays.asList(
new Person("Alice", 25),
new Person("Bob", 30),
new Person("Charlie", 22)
);

// Apply sorting strategy at runtime
Collections.sort(people, new NameComparator());
System.out.println("Sorted by name: " + people);
```
---
## Design Principles

> [!Note] Note
> 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.
- **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.
- **Favor Composition Over Inheritance** - Instead of using inheritance on extending functionality, rather use composition by delegating behavior to other objects.
- **Program to Interface not Implementations** - Write code that depends on Abstractions or Interfaces rather than Concrete Classes.
---

Binary file added public/Images/Pasted-image-20250212000000.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 1414ffb

Please sign in to comment.