觀察者模式定義:在對象之間定義一對多的關系,當主對象改變狀態(tài),依賴它的對象都會收到通知,作出相應的改變。
這種模式在現(xiàn)實中比較常見:比方說,炒股的過程中,股票行情可以當做主對象,股票玩家就是模式中的觀察者。當股票行情變化時,炒股者觀察或者監(jiān)聽到行情的變化,就會作出買,賣的行為。
再比方說,有一個獵頭,有一群求職者是他的客戶,獵頭從委托公司獲取職位信息,一旦獲取到新的職位需求,就會逐個通知他的客戶,讓他們準備去面試。獵頭就是模式中的主對象,各個求職者組成模式中的觀察者。
UML如下:

image.png
觀察者模式中角色如下:
1、主體接口(HeadHunter),這個接口是主體類的抽象。一般,對觀察者的添加,刪除都在里面定義,包括狀態(tài)更新后通知觀察者的方法。
2、主體類(ConcreteHeadHunter),這個是主體接口的一個具體實現(xiàn),主體類中會維護一個觀察者的列表。主體類負責維護觀察者的增,減和狀態(tài)變更通知。
3、觀察者接口(Observer),各種類型的觀察者的一個抽象,用于規(guī)范所有觀察者的共有行為。
4、具體的觀察者類(FirstObserver、SecondObserver),主體類變化之后,會通知各個觀察者,各個觀察者更具變化執(zhí)行自己的操作
代碼如下:
/**
* 模式中主體類的接口,觀察者的維護和通知都在此處定義
* @author saisaimayi
*
*/
public interface HeadHunter {
/**
* 注冊觀察者
* @param observer
*/
public void registerObserver(Observer observer);
/**
* 刪除觀察者
* @param observer
*/
public void removeObserver(Observer observer);
/**
* 更新工作
*/
public void updateJob();
/**
* 通知所有觀察者
*/
public void notifyObservers();
}
/**
* 具體的主體類
* @author saisaimayi
*
*/
public class ConcreteHeadHunter implements HeadHunter {
private List<Observer> observerList = new ArrayList<Observer>();
public void registerObserver(Observer observer) {
observerList.add(observer);
}
public void removeObserver(Observer observer) {
observerList.remove(observer);
}
public void updateJob() {
System.out.println("來了一個新工作,我要通知那些找工作的家伙...");
notifyObservers();
}
public void notifyObservers() {
//逐個通知觀察者
for (Observer observer : observerList) {
observer.interview();
}
}
}
/**
* 觀察者接口,定義所有觀察者的共用行為
* @author saisaimayi
*
*/
public interface Observer {
public void setName(String name);
/**
* 參加面試
*/
public void interview();
}
/**
* 求職者一(觀察者)
* @author saisaimayi
*
*/
public class FirstObserver implements Observer {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void interview() {
System.out.println(name+" prepare to interview...");
}
}
/**
* 求職者二(觀察者)
* @author saisaimayi
*
*/
public class SecondObserver implements Observer {
private String name = "Frank";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void interview() {
System.out.println(name+" prepare to interview...");
}
}
public class Client extends TestCase {
public void test(){
HeadHunter hunter = new ConcreteHeadHunter();
Observer javadev = new FirstObserver();
javadev.setName("Jack");
Observer cdev = new SecondObserver();
hunter.registerObserver(javadev);
hunter.registerObserver(cdev);
hunter.updateJob();
}
}