The observer pattern for Java design patterns

Source: Internet
Author: User

Observer Pattern is to define a one-to-many dependency between objects, and when the state of an object changes, all objects that depend on it are notified and automatically updated. The key objects in this pattern are the target (SUBJECT) and the Observer (Obserber). A target can have any observer, and once the target state changes, all observers will be notified. This interaction is also known as a publish-subscribe .

Application scenarios for the Observer pattern:

When an abstract model has two facets, one aspect depends on the other. The two are encapsulated in separate objects so that they can be individually changed and reused.

When a change to an object needs to change other objects at the same time, it is not known how many objects need to be changed.

When an object must notify other objects, it cannot assume that other objects are who. In other words, you don't want these objects to be tightly coupled.

Basic structure:

subject<---------ConcreteSubject

observer<----------Concreteobserver

Subject (target): the target knows its observer, can have any observer, and provides attach (), detach (), Notifyobservers () method interfaces.

ConcreteSubject (target): writes the state or content of a specific target object (getter and setter methods) and notifies its observers when their state changes .

OBSERVER (Observer): Defines an interface, Update () method for an object that needs to be notified when a target is changed.

? Concreteobserver (Specific observer): ? maintains a reference to the ConcreteSubject object, stores the observer's own State, and implements the Observer interface to keep its state consistent with the target State.

The Observer pattern allows independent changes to the target and observer. The target object can be reused independently without having to reuse its observers at the same time, and vice versa.

The advantages of the Observer pattern: the abstract coupling between the target and the observer, the least coupling and abstraction, and the support of the broadcast update.

The disadvantage of the Observer pattern: it is prone to false broadcasts, where one of the observers modifies the state of the target, and other observers receive the update.

The observer pattern implementation needs to consider the following key points: 1. Create a mapping between the target to its observer, 2. Observe multiple targets, 3. who triggered the update; 4. Hanging references to deleted targets; 5. Be sure to ensure that the status of the target is consistent before giving notice; 6. Avoid observer-specific update protocols-- Push/Pull Model: A push model is a goal that sends detailed information about the change to the viewer, whether they need it or not. Pull model refers to the goal of the target in addition to the minimum notice is not sent out, and thereafter by the observer to the target to ask the details. 7. Specify the change of interest in the display. That allows the observer to accept the notification for the target of interest.


Here's a piece of code to illustrate the Observer Pattern application case:

Subject.java

package com.observer.classic;import java.util.arraylist;import java.util.list;/** *  Observer patterns  *  target objects  *  @author  zzw */public class subject {// Different points of interest observer linear list private list<observer> observersall = new arraylist<observer> ();p rivate list<observer> observersmusic = new arraylist<observer> (); Private list<observer> observerssport = new arraylist<observer> ();p rivate  List<Observer> observersMovie = new ArrayList<Observer> ();//Increase observer public  void attach (Observer observer)  {String interest =  Observer.getobserverinterest (), if ("All". Equals (Interest)) &NBSP;{OBSERVERSALL.ADD (Observer);}  else if ("Music". Equals (Interest)) &NBSP;{OBSERVERSMUSIC.ADD (Observer);}  else if ("Sport". Equals (Interest)) &NBSP;{OBSERVERSSPORT.ADD (Observer);}  else if("Movie". Equals (Interest)) &NBSP;{OBSERVERSMOVIE.ADD (Observer);}} Delete Viewer Public void detach (observer observer)  {String interest =  Observer.getobserverinterest (), if ("All". Equals (Interest))  {observersall.remove (Observer);}  else if ("Music". Equals (Interest))  {observersmusic.remove (Observer);}  else if ("Sport". Equals (Interest))  {observerssport.remove (Observer);}  else if ("Movie". Equals (Interest))  {observersmovie.remove (Observer);}} Public void notifyobservers (String subjecttag)  {if ("Music". Equals (Subjecttag))  {for ( Observer observer : observersmusic)  {observer.update (this);}}  else if ("Sport". Equals (Subjecttag))  {for (Observer observer : observerssport)  {observer.update (this);}}  else if ("Movie". Equals (Subjecttag))  {for (Observer observer : observersmovie)  {observer.update (this);}} for (Observer obserVer : observersall)  {observer.update (this);}}} 


Observer.java

Package com.observer.classic;/** * Viewer interface * @author ZZW * */public interface Observer {public void Update (Subject Subject); Public String getobserverinterest ();}

Concretesubject.java

Package com.observer.classic;/** * Specific target object * Responsible for storing the status information of the target on the corresponding observer * @author ZZW */public class ConcreteSubject extends Su bject {//the status of the corresponding target (content) private string subjectstate;//the category label of the target notification private string Subjecttag;public string Getsubjecttag () { return Subjecttag;} Public String Getsubjectstate () {return subjectstate;} public void Setsubjectstate (String subjectstate,string subjecttag) {this.subjectstate = Subjectstate;this.subjecttag = Subjecttag;this.notifyobservers (Subjecttag);}}

Concreteobserver.java

package com.observer.classic;public class concreteobserver implements observer { Observer name private string observername;//Observer interest Point private string observerinterest;// Observer status information Private string observerstate;public string getobservername ()  {return  Observername;} Public void setobservername (String observername)  {this.observerName =  Observername;} Public string getobserverstate ()  {return this.observerstate;} Public string getobserverinterest ()  {return observerinterest;} Public void setobserverinterest (string observerinterest)  {this.observerinterest =  observerinterest;} @Overridepublic  void update (subject subject)  {//gets the target state to keep the update observerstate =  ( ConcreteSubject)  subject). Getsubjectstate (); System.out.println (observername +  "received a notification:"  + observerstate);}}


Test.java

Package com.observer.classic;public class test {public static void main ( String[] args)  {//  Create push content 1concretesubject concretesubject = new  ConcreteSubject ();//  create observers (i.e. objects to be notified) concreteobserver concreteobserver1 = new  Concreteobserver (); Concreteobserver1.setobservername ("Zhang San"); Concreteobserver1.setobserverinterest ("All"); Concreteobserver concreteobserver2 = new concreteobserver (); Concreteobserver2.setobservername ("John Doe"); Concreteobserver2.setobserverinterest ("Music"); Concreteobserver concreteobserver3 = new concreteobserver (); Concreteobserver3.setobservername ("King of the two Leper"); Concreteobserver3.setobserverinterest ("Sport"); Concreteobserver concreteobserver4 = new concreteobserver (); Concreteobserver4.setobservername ("Liu Lao Wu"); Concreteobserver4.setobserverinterest ("Movie");// Registered observer Concretesubject.attach (CONCRETEOBSERVER1); Concretesubject.attach (ConcreteobservER2); Concretesubject.attach (ConcreteObserver3); Concretesubject.attach (concreteObserver4);// Release notification 1system.out.println ("message One:"); Concretesubject.setsubjectstate ("Jay Chou made a new album" Ouch, Good Oh "," Music ");// Announcement 2SYSTEM.OUT.PRINTLN ("message two:"); Concretesubject.setsubjectstate ("Yao Ming announces retirement", "Sport");//Publish Notification 3SYSTEM.OUT.PRINTLN (" Message three: "Concretesubject.setsubjectstate" ("new film" Gardenia Opens "," movie ");}}

Run results

Message One:

John Doe received a notice: Jay Chou made a new album "Ouch, Good Oh"

Zhang San received a notice: Jay Chou made a new album "Ouch, Good Oh"

Message two:

Wang er the leper received a notice: Yao Ming announced his retirement

Zhang San received a notice: Yao Ming announced his retirement.

Message Three:

Liu Lou received a notice: The new film "Gardenia Blossom" released

Zhang San received a notice: The new film "Gardenia Blossom" released


Here's another way to implement a differentiated observer, by leaving the Notifyobservers method in the subclass, and the parent class providing only abstract methods.

Weathersubject.java

Package com.observer.advanced;/** * Viewer Mode Advanced * Allows the push of content to a specific observer * NOTIFYOBSERVERS () to implement */import java.util.ArrayList in subclasses; Import Java.util.list;public abstract class Weathersubject {list<observer> observers = new arraylist<observer& gt; ();p ublic void Attach (Observer Observer) {observers.add (Observer);} public void Detach (Observer Observer) {observers.remove (Observer);} Save to subclass to implement protected abstract void Notifyobservers ();}

Concreteweathersubject.java

package com.observer.advanced;public class concreteweathersubject extends  weathersubject {//Target State Private string subjectstate;public concreteweathersubject (String  subjectstate)  {super (); this.subjectstate = subjectstate;} Public string getsubjectstate ()  {return subjectstate;} Public void setsubjectstate (string subjectstate)  {this.subjectState =  subjectstate;//once the target has been modified, all observers will be notified This.notifyobservers ();} @Overrideprotected  void notifyobservers ()  {/** *  because Zhang three only accepts snow weather forecast, Li four accepts the weather forecast of rain, other observers unrestricted  */for (observer observer : observers)  {if ("Snow". Equals (Subjectstate))  {if ("Zhang San". Equals (Observer.getobservername ())) observer.update (this); Else if (! " John Doe ". Equals (Observer.getobservername ())) observer.update (this);} Else if ("Rain". Equals (Subjectstate))  {if ("John Doe". Equals (Observer.getobservername ())) Observer.update (this) ; Else if (! " Zhang San ". EQuals (Observer.getobservername ())) observer.update (this);} ElseIf (! " John Doe ". Equals (Observer.getobservername ()) &&!" Zhang San ". Equals (Observer.getobservername ())) observer.update (this);}}

Observer.java

Package Com.observer.advanced;public interface Observer {public void Update (weathersubject subject);//set observer name public String Getobservername ();p ublic void Setobservername (string observername);p ublic String getobserversex ();p ublic void Setobserversex (String observersex);p ublic string getobserverage ();p ublic void Setobserverage (string observerage);}

Concreteobserver.java

package com.observer.advanced;public class concreteobserver implements observer  {private string observername;private string observersex;private string  Observerage;public concreteobserver (string observername, string observersex,string  Observerage)  {super (); this.observername = observername;this.observersex = observersex ; this.observerage = observerage;} @Overridepublic  void update (weathersubject subject)  {//  push content string content  =  ((concreteweathersubject) subject). Getsubjectstate (); System.out.println (This.getobservername () + "(" +this.getobserversex () + "," +this.getobserverage () + ") received a message:" + content);} @Overridepublic  string getobservername ()  {return observername;} @Overridepublic  void setobservername (string observername)  {this.observerName =  Observername;} Public string getobserveragE ()  {return observerage;} Public void setobserverage (String observerage)  {this.observerage = observerage;} Public string getobserversex ()  {return observersex;} Public void setobserversex (String observersex)  {this.observersex = observersex;}}

Test.java

Package com.observer.advanced;public class test {public static void main ( String[] args)  {//new three observers observer concreteobserver1 = new concreteobserver ("Zhang San",   "Male",  "22 years old"), Observer concreteobserver2 = new concreteobserver ("John Doe",  "male",   "30 years old"), Observer concreteobserver3 = new concreteobserver ("Mary",  "female",  "25 years old") ;//New Target content: Snow Weathersubject concreteweathersubject1 = new concreteweathersubject ("Snow"); Concreteweathersubject1.attach (ConcreteObserver1); Concreteweathersubject1.attach (ConcreteObserver2); Concreteweathersubject1.attach (ConcreteObserver3); concreteweathersubject1.notifyobservers ();// New target content: Rain Weathersubject concreteweathersubject2 = new concreteweathersubject ("Rain"); Concreteweathersubject2.attach (ConcreteObserver1); Concreteweathersubject2.attach (ConcreteObserver2); Concreteweathersubject2.attach (CONCRETEOBSERVER3); ConcreteweaThersubject2.notifyobservers ();//New Target content: Sunny weathersubject concreteweathersubject3 = new  Concreteweathersubject ("Sunny Day"); Concreteweathersubject3.attach (ConcreteObserver1); Concreteweathersubject3.attach ( CONCRETEOBSERVER2); Concreteweathersubject3.attach (ConcreteObserver3); Concreteweathersubject3.notifyobservers () ;}}


Operation Result:

Zhang San (male, 22 years old) received a message: Snow

Mary (Female, 25 years old) received a message: Snow

John Doe (male, 30 years old) received a message: rain

Mary (Female, 25 years old) received a message: rain

Mary (Female, 25 years old) received a message: Sunny day


The observer pattern for Java design patterns

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.