寫在前面
鉤子函數、註冊函數、回調函數,他們的概念實際上是同樣的。
觀察者模式,又能夠稱之爲發佈-訂閱模式,觀察者,顧名思義,就是一個監聽者,相似監聽器的存在,一旦被觀察/監聽的目標發生的狀況,就會被監聽者發現,這麼想來目標發生狀況到觀察者知道狀況,實際上是由目標獎狀況發送到觀察者的。 觀察者模式多用於實現訂閱功能的場景,例如微博的訂閱,當咱們訂閱了某我的的微博帳號,當這我的發佈了新的消息,就會通知咱們。
觀察者模式警匪電影版
觀察者接口 (觀察者多是警察,也多是線人)
public interface Observer { void report(String message,String name); }
觀察者實現類 (警察)
public class Policeman implements Observer { private String name; Policeman(String name){this.name = name;} @Override public void report(String message, String name) { System.out.println(this.name+"發現"+name+":"+message); } }
觀察者實現類(線人)
public class Informers implements Observer { private String name; Informers(String name){this.name = name;} @Override public void report(String message, String name) { System.out.println(this.name+"發現"+name+":"+message); } }
被觀察者(壞人) 接口 (具體多是 小偷,毒販等。。。)
public interface BadGuy { void addObserver(Observer observer); void removeObserver(Observer observer); void doSomething(String message); }
小偷
import java.util.Queue; import java.util.concurrent.LinkedBlockingQueue; public class Thief implements BadGuy { Queue<Observer> queue = new LinkedBlockingQueue<Observer>(); private String name; Thief(String name){this.name = name;} @Override public void addObserver(Observer observer) { if(!queue.contains(observer)){ queue.add(observer); } } @Override public void removeObserver(Observer observer) { if(queue.contains(observer)){ queue.remove(observer); } } @Override public void doSomething(String message) { System.out.println(this.name+" : "+message); for(Observer observer:queue){ observer.report(message,this.name); } } }
毒販
import java.util.Queue; import java.util.concurrent.LinkedBlockingQueue; public class Dealer implements BadGuy { private String name; Dealer(String name){this.name = name;} Queue<Observer> queue = new LinkedBlockingQueue<Observer>(); @Override public void addObserver(Observer observer) { if(!queue.contains(observer)){ queue.add(observer); } } @Override public void removeObserver(Observer observer) { if(queue.contains(observer)){ queue.remove(observer); } } @Override public void doSomething(String message) { System.out.println(this.name+":"+message); for(Observer observer:queue){ observer.report(message,this.name); } } }
##最後測試一下java
public class ObserverDemo { public static void main(String [] args){ Observer policeman = new Policeman("李警官"); Observer informers = new Informers("線人A"); BadGuy thief = new Thief("小偷甲"); BadGuy dealer = new Dealer("毒販阿爾法"); thief.addObserver(policeman); thief.addObserver(informers); thief.doSomething("此處人傻錢多速來"); dealer.addObserver(policeman); dealer.addObserver(informers); dealer.doSomething("新貨已到達..."); //線人被毒販發現被幹掉 dealer.removeObserver(informers); dealer.doSomething("線人被幹掉了!"); //警察被毒販發現犧牲了 dealer.removeObserver(policeman); dealer.doSomething("警察也犧牲了!"); dealer.doSomething("如今我能夠沒法無天了。。。哈哈哈哈!!!"); new Runnable() { @Override public void run() { try{ Thread.sleep(1000); System.out.println("天降正義!!! 毒販被一位不肯意透露姓名的大佬帶走。。。"); } catch(InterruptedException e){ e.printStackTrace(); } } }.run(); } }
結果
小偷甲 : 此處人傻錢多速來 李警官發現小偷甲:此處人傻錢多速來 線人A發現小偷甲:此處人傻錢多速來 毒販阿爾法:新貨已到達... 李警官發現毒販阿爾法:新貨已到達... 線人A發現毒販阿爾法:新貨已到達... 毒販阿爾法:線人被幹掉了! 李警官發現毒販阿爾法:線人被幹掉了! 毒販阿爾法:警察也被幹掉了! 毒販阿爾法:如今我能夠沒法無天了。。。哈哈哈哈!!! 天降正義!!! 毒販被一位不肯意透露姓名的大佬帶走。。。
###總結ide
關鍵點: 一、針對觀察者與被觀察者分別定義接口,有利於分別進行擴展。 二、重點就在被觀察者的實現中: (1)定義觀察者集合,並定義針對集合的添加、刪除操做,用於增長、刪除訂閱者(觀察者) (2)定義通知方法,用於將新狀況通知給觀察者用戶(訂閱者用戶) 三、觀察者中須要有個接收被觀察者通知的方法。