Twenty three design patterns in JAVA -- Observer Pattern

Posted by j007w on Sun, 06 Feb 2022 05:14:37 +0100

concept

When there is a one to many relationship between objects, the Observer Pattern is used. For example, when an object is modified, it will automatically notify the objects that depend on it. Observer mode belongs to behavioral mode.

introduce

Intent: defines a one to many dependency between objects. When the state of an object changes, all objects that depend on it are notified and automatically updated.

It mainly solves the problem of notifying other objects of an object's state change. In addition, it should consider ease of use and low coupling to ensure a high degree of cooperation.

When to use: when the state of an object (target object) changes, all dependent objects (observer object) will be notified and broadcast.

How to solve it: using object-oriented technology can weaken this dependency.

Key code: there is an ArrayList in the abstract class to store the observers.

Application examples: 1. During the auction, the auctioneer observes the highest bid price and then notifies other bidders to bid. 2. In the journey to the west, Wukong asks the Bodhisattva to subdue the red boy. The Bodhisattva sprinkles water on the ground to attract an old tortoise. The tortoise is the observer. He observes the Bodhisattva's action of sprinkling water.

Advantages: 1. The observer and the observed are abstractly coupled. 2. Establish a trigger mechanism.

Disadvantages: 1. If an observed object has many direct and indirect observers, it will take a lot of time to notify all observers. 2. 2. If there is a circular dependency between the observer and the observation target, the observation target will trigger a circular call between them, which may lead to system crash. 3. The observer model has no corresponding mechanism to let the observer know how the observed target object has changed, but only know that the observed target has changed.

Usage scenario:

An abstract model has two aspects, one of which depends on the other. These aspects are encapsulated in independent objects so that they can be changed and reused independently.
The change of one object will lead to the change of one or more other objects, and the coupling between objects can be reduced by not knowing how many objects will change.
An object must notify other objects without knowing who they are.
You need to create A trigger chain in the system. The behavior of object A will affect object B, and the behavior of object B will affect object C.. You can use the observer mode to create A chain trigger mechanism.
Notes: 1. There are already support classes for observer mode in JAVA. 2. Avoid circular references. 3. If the sequence is executed, an observer error will cause the system to jam, and the asynchronous mode is generally adopted.

code

import java.util.ArrayList;
import java.util.List;
 
public class Subject {
   
   private List<Observer> observers 
      = new ArrayList<Observer>();
   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();
      }
   }  
}
public abstract class Observer {
   protected Subject subject;
   public abstract void update();
}
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() ) ); 
   }
}
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() ) ); 
   }
}
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() ); 
   }
}
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);
   }
}

Output result:

First state change: 15
Hex String: F
Octal String: 17
Binary String: 1111
Second state change: 10
Hex String: A
Octal String: 12
Binary String: 1010

Topics: Java Design Pattern