觀察者模式也是比較簡單的一種模式,可能從名字上理解無法明白,但真正理解其含義之後就非常簡單了,說實話在自己來發的項目中自己也用到過,只不過不知道它叫觀察者罷了,只要懂面向對象的對繼承多態理解很深的,玩觀察者模式很隨意就能用到項目中去。
這本書用一個很形象的故事解釋了觀察者模式,故事情景:公司員工當老闆不在時有的炒股有的看NBA,爲了防止老闆偷襲,讓前臺MM通知。即前臺MM充當了觀察者,而員工屬於具體的實例對象了。我們要編寫的代碼就是MM作爲通知類,員工作爲被通知者,
觀察者模式:定義了一種一對多的依賴關係,讓多個觀察者對象同事監聽某一個主題對象。這個主題對象在狀態發生變化時,會通知所有觀察者對象,使它們能夠自動更新自己。
如何實現呢?請看代碼吧
1、觀察者接口(定義所有觀察者的屬性,在此不一定就是前臺MM通知)
/**
* @author jzhf
* 2014-10-31
* 通知類
*/
public interface Subject {
public abstract void add(Observer observer);
public abstract void notifyEveryOne();
public final String message = "老闆來了";
}
2、前臺MM繼承觀察者接口(因爲它要把風)
/**
* @author jzhf
* 2014-10-31
* 祕書通知大家老闆來了
*/
public class Secretary implements Subject{
private List<Observer> list = new ArrayList<Observer>();
/* (non-Javadoc)
* @seecom.test.model.observer.Subject#notifyEveryOne()
* 通知每一個人
*/
public void notifyEveryOne(){
// TODO Auto-generatedmethod stub
for(Observer observer : list){
observer.Update();
}
}
/* (non-Javadoc)
* @seecom.test.model.observer.Subject#add(com.test.model.observer.Observer)
*/
public void add(Observer observer) {
// TODO Auto-generatedmethod stub
list.add(observer);
}
}
3、還有一個通知大家的就是老闆了(老闆來了直接對他們說別玩了工作吧),和前臺類一樣,在此略(只是類名不同而已,本人定義的類名是Boss)
4、開始定義具體類了,有的員工在看股票,有的看NBA,所以要用抽象類定義共同的動作了。
/**
* @author jzhf
* 2014-10-31
* 對觀察者即工作時間玩其他的人的抽象類
*/
public abstract class Observer {
public String name;
public Subject sub;
public Observer(String name,Subject sub){
this.name = name;
this.sub = sub;
}
public abstract void Update();
}
5、看股票的
/**
* @author jzhf
* 2014-10-31
*/
public class StockObserver extends Observer{
public StockObserver(String name,Subject sub){
super(name, sub);
}
/* (non-Javadoc)
* @seecom.test.model.observer.Observer#Update()
*/
@Override
public void Update() {
// TODO Auto-generatedmethod stub
System.out.print(sub.message+this.name+"關閉股票行情,繼續工作");
}
}
6、看NBA的
/**
* @author jzhf
* 2014-10-31
*/
public class NBAObserver extends Observer{
public NBAObserver(String name,Subject sub){
super(name, sub);
}
/* (non-Javadoc)
* @seecom.test.model.observer.Observer#Update()
*/
@Override
public void Update() {
// TODO Auto-generatedmethod stub
System.out.println(sub.message+this.name+"關閉NBA,繼續工作");
}
}
7、客戶端
/**
* @author jzhf
* 2014-10-31
*/
public class ObserverClient {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generatedmethod stub
//祕書通知
Subject sub = new Secretary();
Observer observer = new StockObserver("老李", sub);
sub.add(observer);
Observer observer2 = new NBAObserver("老王", sub);
sub.add(observer2);
sub.notifyEveryOne();
//老闆通知
Subject sub2 = new Boss();
Observer observer3 = new StockObserver("老李", sub);
sub2.add(observer3);
Observer observer4 = new NBAObserver("老王", sub);
sub2.add(observer4);
sub2.notifyEveryOne();
}
}
如果你看完程序我相信你已經理解了觀察者模式了,觀察者模式所做的工作其實就是解除耦合,讓耦合的雙方都依賴於抽象,而不是依賴於具體。從而使得各自的變化都不會影響另一邊的變化。
附上觀察者模式結構圖
總結:當一個對象的改變需要同時改變其他對象的時候,而且它不知道具體有多少對象有待改變時,應該考慮使用觀察者模式。當系統中一個對象依賴於另一個對象,這時用觀察者模式可以將這兩個封裝在獨立的對象中使用它們各自獨立地改變和複用。