Observer Pattern
# Observer Pattern
The Observer Pattern is a behavioral design pattern that defines a one-to-many dependency between objects. When one object (the subject) changes its state, all its dependents (observers) are notified and updated automatically.
The Observer Pattern is used when there is a one-to-many relationship between objects. For example, when one object is modified, it automatically notifies all objects that depend on it. The Observer Pattern belongs to the behavioral pattern category.
## Introduction
### Intent
Create a one-to-many dependency between objects such that when one object changes state, all its dependents are notified and updated automatically.
### Main Problem Solved
* The Observer Pattern addresses the problem of how to automatically notify other dependent objects when one object's state changes, while maintaining low coupling and high collaboration between objects.
### Use Cases
* When a change in one object's state requires updating multiple other objects simultaneously.
### Implementation Approach
* **Define the Observer Interface**: Contains an update method.
* **Create Concrete Observers**: Implement the observer interface, defining the behavior upon receiving a notification.
* **Define the Subject Interface**: Contains methods to add, remove, and notify observers.
* **Create Concrete Subjects**: Implement the subject interface, manage the list of observers, and notify them when the state changes.
### Key Code
* **Observer List**: Maintain a list of observers within the subject.
### Application Examples
* **Auction System**: The auctioneer is the subject, bidders are observers. When the auction price updates, all bidders are notified.
* **Journey to the West Story**: The Bodhisattva sprinkling water is the state change, the old turtle is the observer who observes this change.
### Advantages
* **Abstract Coupling**: The subject and observers are abstractly coupled.
* **Trigger Mechanism**: Establishes a trigger and notification mechanism for state changes.
### Disadvantages
* **Performance Issues**: If there are many observers, the notification process can be time-consuming.
* **Circular Dependencies**: Can lead to circular calls and system crashes.
* **Lack of Change Details**: Observers do not know how the subject changes, only that a change occurred.
### Usage Recommendations
* Use when you need to reduce coupling between objects, and changes in an object's state need to trigger changes in other objects.
* Consider using Java's built-in observer pattern support classes, such as `java.util.Observable` and `java.util.Observer`.
### Considerations
* **Avoid Circular References**: Pay attention to the dependencies between observers and subjects to avoid circular references.
* **Asynchronous Execution**: Consider using asynchronous notifications to prevent a single point of failure from blocking the entire system.
### Structure
**The Observer Pattern includes the following core roles:**
* **Subject**: Also known as the observable or publisher. It is an object with state and maintains a list of observers. The subject provides methods to add, remove, and notify observers.
* **Observer**: The observer is the object that receives notifications from the subject. Observers need to implement an update method, which is called to perform an update operation when a notification from the subject is received.
* **Concrete Subject**: The concrete subject is the specific implementation class of the subject. It maintains the list of observers and notifies them when its state changes.
* **Concrete Observer**: The concrete observer is the specific implementation class of the observer. It implements the update method, defining the specific operations to be performed when a notification from the subject is received.
The Observer Pattern decouples the subject and observers, achieving loose coupling between objects. When the subject's state changes, all observers that depend on it are notified and perform the corresponding updates.
## Implementation
The Observer Pattern uses three classes: Subject, Observer, and Client. The Subject object has methods to bind observers to the Client object and unbind observers from it. We create the _Subject_ class, the _Observer_ abstract class, and entity classes that extend the abstract class _Observer_.
_ObserverPatternDemo_, our demonstration class, uses the _Subject_ and entity class objects to demonstrate the Observer Pattern.

### Step 1
Create the Subject class.
## Subject.java
import java.util.ArrayList; import java.util.List; public class Subject{private Listobservers = new ArrayList(); private int state; public int getState(){return state; }public void setState(int state){this.state = state; notifyAllObservers(); }public void attach(Observer observer){observers.add(observer); }public void notifyAllObservers(){for(Observer observer : observers){observer.update(); }}}
### Step 2
Create the Observer class.
## Observer.java
public abstract class Observer{protected Subject subject; public abstract void update(); }
### Step 3
Create concrete observer classes.
## BinaryObserver.java
public class BinaryObserver extends Observer{public BinaryObserver(Subject subject){this.subject = subject; this.subject.attach(this); } @Override public void update(){System.out.println("Binary String: " + Integer.toBinaryString(subject.getState())); }}
## OctalObserver.java
public class OctalObserver extends Observer{public OctalObserver(Subject subject){this.subject = subject; this.subject.attach(this); } @Override public void update(){System.out.println("Octal String: " + Integer.toOctalString(subject.getState())); }}
## HexaObserver.java
public class HexaObserver extends Observer{public HexaObserver(Subject subject){this.subject = subject; this.subject.attach(this); } @Override public void update(){System.out.println("Hex String: " + Integer.toHexString(subject.getState()).toUpperCase()); }}
### Step 4
Use the _Subject_ and concrete observer objects.
## ObserverPatternDemo.java
public class ObserverPatternDemo{public static void main(String[]args){Subject subject = new Subject(); new HexaObserver(subject); new OctalObserver(subject); new BinaryObserver(subject); System.out.println("First state change: 15"); subject.setState(15); System.out.println("Second state change: 10"); subject.setState(10); }}
### Step 5
Execute the program, output:
First state change: 15Hex String: F Octal String: 17Binary String: 1111Second state change: 10Hex String: A Octal String: 12Binary String: 1010
YouTip