In brief, Observer Pattern = publisher + subscriber.
Observer pattern has been used in GUI action listener. Swing GUI example shows how action listener works like an observer.
The following is a typical example about head hunter. There are two roles in this diagram –
Class Diagram
Java Code
Subject interface.
public interface Subject { public void registerObserver(Observer o); public void removeObserver(Observer o); public void notifyAllObservers(); } |
Observer interface.
public interface Observer { public void update(Subject s); } |
HeadHunter class implements Subject.
import java.util.ArrayList; public class HeadHunter implements Subject{ //define a list of users, such as Mike, Bill, etc. private ArrayList<Observer> userList; private ArrayList<String> jobs; public HeadHunter(){ userList = new ArrayList<Observer>(); jobs = new ArrayList<String>(); } @Override public void registerObserver(Observer o) { userList.add(o); } @Override public void removeObserver(Observer o) {} @Override public void notifyAllObservers() { for(Observer o: userList){ o.update(this); } } public void addJob(String job) { this.jobs.add(job); notifyAllObservers(); } public ArrayList<String> getJobs() { return jobs; } public String toString(){ return jobs.toString(); } } |
JobSeeker is an observer.
public class JobSeeker implements Observer { private String name; public JobSeeker(String name){ this.name = name; } @Override public void update(Subject s) { System.out.println(this.name + " got notified!"); //print job list System.out.println(s); } } |
Start Point.
public class Main { public static void main(String[] args) { HeadHunter hh = new HeadHunter(); hh.registerObserver(new JobSeeker("Mike")); hh.registerObserver(new JobSeeker("Chris")); hh.registerObserver(new JobSeeker("Jeff")); //Each time, a new job is added, all registered job seekers will get noticed. hh.addJob("Google Job"); hh.addJob("Yahoo Job"); } } |
Observer pattern in JDK
Following the example: what if there are multiple head-hunters each adding new jobs. A certain head-hunter is sending too many jobs and Jeff doesn’t like that. You can implement it simply by:
if (this.name.equals(“Jeff”) && ((HeadHunter)s).getJobs().size() > 10) { s.removeObserver(this); }
Now, imagine you don’t have access to the subject, only the jobs list. How would you know who sent it to you and tell them to shut up?
I thought so as well.
why pass the Subject to the Observer? Is it necessary?In my opinion, only job list is enough?
greatï¼