java observer mode & source with observer mode analysis

Posted by mandrews81 on Sat, 13 Jul 2019 18:32:02 +0200

Recently I feel that I can't learn much in my work, I am busy starting to change my work, and I am not very solid in my study. I have already started to fill in the things that were backward before. Updating my blog may gradually become less and less. Although I should start writing, I feel very shallow in my knowledge, and I don't understand enough in all aspects, although very little.The word version of multi-blog still exists on the computer, and many bugs are found when you read it yourself, so you will strengthen yourself first, and then show your good notes in the blog, hoping you can grow quickly.

Observer mode:

1 Concept

An observer, also known as a publish-subscribe mode, defines a one-to-many dependency between objects. A subject object can be monitored by multiple listeners. When the state of a subject object changes, all registered listeners can receive the change information and update it accordingly.

The object whose state can change is called the observer, and the object notified is called the observer.An observation target can correspond to multiple observers, which are not related to each other, and can be added or deleted as needed, making the system easier to expand.

 

2. Roles in patterns

 

2.1 Abstract Theme (Subject): An abstract theme can be composed of multiple observers, all registered observers will be placed in a collection (if defined as an interface, the collection will appear in a specific theme), an abstract theme provides an interface to add and delete observers, and a state change calls the observer-specificThe interface of the method.

2.2 ConcreteSubject: Save the relevant state in the specific observer object; notify all registered observers when the internal state of the specific subject changes.

2.3 Abstract Observer: Define an interface for all specific observers to update themselves when notified of a subject.

2.4 ConcreteObserver: Implement the update interface required by the abstract observer role to reconcile its own state with the subject state.

3 Observer pattern class diagram structure

 

4 Scenarios applicable

(1) Changes in one object can lead to changes in the state of many other objects. The observer mode can reduce the coupling between objects, and each part can be changed and reused independently.

(2) Objects only need to inform other objects of their updates without knowing the details of other objects, which reduces the coupling between objects.

 


Code implementation:

 

Define the scenario below to implement the observer mode. News from Xinlang and Tengxun is obtained from a specific entity. When new news arrives, Xinlang and Tengxun are not required to make an active request. The news entity receives changes and automatically pushes news to Xinlang and Tengxun. This implements the observer mode.

 

/**
 * Abstract Subject
 * @author ldx
 *@category: The collection of stored observers is no longer implemented here because it is defined as an interface
 */
interface Subject {
 
   //Responsible for registering observers
   public voidregisterObserver(Observer observer);
  
   //Responsible for deleting observers
   public void removeOberver(Observer observer);
  
   //Notify that the status has changed to respond
   public void notifyChange();
  
}


interface Observer {
 
   public void update(String news);
}


public classSubjectContent implements Subject{
   privateArrayList<Observer> arraylist;
   private String news;
  
   //You can define the watcher's initial incoming
   /*public SubjectContent1(ArrayList<Observer> arraylist){
      arraylist=newArrayList<>();
      this.arraylist= arraylist;
   }
   */
   public SubjectContent() {
      arraylist=new ArrayList<>();
   }
   @Override
   public voidregisterObserver(Observer observer) {
 
    arraylist.add(observer);
   }
 
   @Override
   public void removeOberver(Observer observer) {
      if (!arraylist.isEmpty()) {
        arraylist.remove(observer);
      }
   }
 
   @Override
   public void notifyChange() {
      for (Observer observer : arraylist) {
        observer.update(this.news);
      }
   }
  
   public void change(String news){
      this.news=news;
      notifyChange();
   }
}
 


public classXinlang implementsObserver {
   @Override
   public void update(String news) {
System.out.println("xinlang news change=="+news);
   }
}
public classTengxun implementsObserver {
   @Override
   public void update(String news) {
System.out.println("Tengxun news change=="+news);
   }
}


 

Advantage:

1. Subject and Observer are loosely coupled and can be changed independently of each other, but can interact well without knowing the specific internal implementation.

2. When Subject sends a broadcast notification, it is not necessary to specify a specific Observer. Observer can decide whether to subscribe to Subject's notification or not.Since it is broadcast, the subject sends notifications to all observers.

3. Comply with most GRASP principles and common design principles, with high cohesion and low coupling.

Disadvantages:

1. If there are many direct and indirect observers for an observed object, it will take a lot of time to notify all the observers.

2. If there is a circular dependency between the observer and the observer target, the observer target triggers a circular call between them, which may cause the system to crash.

3. The observer mode does not have a mechanism for the observer to know how the observed object has changed, only that the observed object has changed.

 

The system also provides us with written observer mode templates:

Subject ->java.util.Observable (class)

Observer -> java.util.Observer (interface)

Class Diagram Description:


public classObservable {
   privatebooleanchanged= false;
   privateVector obs;//Used to store registered observers
   publicObservable() {
        obs = new Vector();
   }
   //Add an observer
public synchronizedvoidaddObserver(Observer o) {
        if (o == null)
            throw new NullPointerException();
        if (!obs.contains(o)){
            obs.addElement(o);
        }
}
//Delete Observer
   publicsynchronizedvoiddeleteObserver(Observer o) {
        obs.removeElement(o);
   }
   publicvoidnotifyObservers() {
        notifyObservers(null);
}
//Notify observers
   publicvoidnotifyObservers(Object arg) {
        Object[] arrLocal;
        synchronized (this) {
            if (!changed)
                return;
            arrLocal = obs.toArray();
            clearChanged();
        }
 
        for (int i = arrLocal.length-1; i>=0; i--)
           ((Observer)arrLocal[i]).update(this, arg);
}
//Delete all observers
   publicsynchronizedvoiddeleteObservers() {
        obs.removeAllElements();
}
//Notify of state change, must be called before notifyObservers()
//Otherwise notifyObservers will not execute
   protectedsynchronizedvoidsetChanged() {
        changed = true;
}
//Empty state, no change
   protectedsynchronizedvoidclearChanged() {
        changed = false;
   }
   publicsynchronizedbooleanhasChanged() {
        return changed;
   }
   publicsynchronizedintcountObservers() {
        return obs.size();
   }
}
public interfaceObserver {
 
   voidupdate(Observable o, Object arg);
}


Add its observers:

void addObserver(Observer o)

The addObserver() method adds an observer object to the list of observer objects

 

When an event in the observer changes, execute

setChanged();

notifyObservers();

The setChange() method is used to set an internal flag bit to indicate that the data has changed; the notifyObservers() method calls the update() method of all Observers in the Observer Object List to notify them that the data has changed.

NotfyObservers() calls update() only after setChange() is called.

The notifyObservers(Objectarg) method of the Observable class, hasChanged() is true, notifies the observer that the data has changed, ultimately by calling the update() method, and after the notification is complete, calls clearChanged() to modify hasChanged() to false, so when the subject data changes, you need to call the setChanged() method first to hasChanGet is true.

 

Java comes with an observer mode instance:

public classNewStation extendsObservable {
 
   private String newsString = null;
 
   public String getNews() {
      return newsString;
   }
 
   public void setNews(String newsString) {
      if (this.newsString == null) {
        this.newsString = newsString;
        setChanged();//Must be called, otherwise notifyObservers() internal logic cannot be triggered
      }
      notifyObservers();
                   
   }
}
 
 
 
public classSohuNewsObserver implements Observer {
   
   publicSohuNewsObserver(NewStation ns) {
     super();
        ns.addObserver(this);
   }
 
   @Override
   publicvoidupdate(Observable arg0,Object arg1){
        System.out.println("sohu Receive news "+((NewStation) arg0).getNews());
 
   }
 
}
 
public classTengxunNewsObserver implements Observer {
   
   publicTengxunNewsObserver(NewStation ns) {
     super();
        ns.addObserver(this);
   }
 
   @Override
   publicvoidupdate(Observable arg0,Object arg1){
        System.out.println("tengxun Receive news "+((NewStation) arg0).getNews());
 
   }
 
}
 
public classXinlangNewsObserver implements Observer {
   
   publicXinlangNewsObserver(NewStation ns) {
     super();
        ns.addObserver(this);
   }
 
   @Override
   publicvoidupdate(Observable arg0,Object arg1){
        System.out.println("xinlang Receive news "+((NewStation) arg0).getNews());
 
   }
 
}
 
public classSystemMainDemo {
 
   public static void main(String[] args) {
 
 NewStation newsStation=newNewStation();
 newSohuNewsObserver(newsStation);
 XinlangNewsObserver xinlangNewsObserver= newXinlangNewsObserver(newsStation);
 newTengxunNewsObserver(newsStation);
 
 newsStation.setNews("new xin wen");
 
   }
}

Finish!If there are any errors, please point them out.

Topics: Java less