java設計模式--事件監聽器模式和觀察者模式
阿新 • • 發佈:2019-01-14
監聽器模式:事件源經過事件的封裝傳給監聽器,當事件源觸發事件後,監聽器接收到事件物件可以回撥事件的方法
觀察者模式:觀察者(Observer)相當於事件監聽者,被觀察者(Observable)相當於事件源和事件,執行邏輯時通知observer即可觸發oberver的update,同時可傳被觀察者和引數
監聽器模式demo
1、首要定義事件源物件(事件源相當於單擊按鈕事件當中的按鈕物件、屬於被監聽者):
- publicclass DemoSource {
- private Vector repository = new Vector();//監聽自己的監聽器佇列
- public
- publicvoid addDemoListener(DemoListener dl) {
- repository.addElement(dl);
- }
- publicvoid notifyDemoEvent() {//通知所有的監聽器
- Enumeration enum = repository.elements();
- while(enum.hasMoreElements()) {
- DemoListener dl = (DemoListener)enum
- dl.handleEvent(new DemoEvent(this));
- }
- }
- }
2、其次定義事件(狀態)物件(該事件物件包裝了事件源物件、作為引數傳遞給監聽器、很薄的一層包裝類):
- publicclass DemoEvent extends java.util.EventObject {
- public DemoEvent(Object source) {
- super(source);//source—事件源物件—如在介面上發生的點選按鈕事件中的按鈕
- //所有 Event 在構造時都引用了物件 "source",在邏輯上認為該物件是最初發生有關 Event 的物件
- }
- publicvoid say() {
- System.out.println("This is say method...");
- }
- }
3、最後定義我們的事件偵聽器介面如下
- publicinterface DemoListener extends java.util.EventListener {
- //EventListener是所有事件偵聽器介面必須擴充套件的標記介面、因為它是無內容的標記介面、
- //所以事件處理方法由我們自己宣告如下:
- publicvoid handleEvent(DemoEvent dm);
- }
監聽器實現類
- publicclass DemoListener1 implements DemoListener {
- publicvoid handleEvent(DemoEvent de) {
- System.out.println("Inside listener1...");
- de.say();//回撥
- }
- }
4、測試程式碼
- publicclass TestDemo {
- DemoSource ds;
- public TestDemo(){
- try{
- ds = new DemoSource();
- //將監聽器在事件源物件中登記:
- DemoListener1 listener1 = new DemoListener1();
- ds.addDemoListener(listener1);
- ds.addDemoListener(new DemoListener() {
- publicvoid handleEvent(DemoEvent event) {
- System.out.println("Method come from 匿名類...");
- }
- });
- ds.notifyDemoEvent();//觸發事件、通知監聽器
- }catch(Exception ex){
- ex.printStackTrace();
- }
- }
- publicstaticvoid main(String args[]) {
- new TestDemo();
- }
- }
觀察者模式demo
觀察者
- class Watcher implements java.util.Observer {
- publicvoid update(java.util.Observable obj, Object arg) {
- System.out.println("Update() called, count is "
- + ((Integer) arg).intValue());
- }
- }
被觀察者
- class BeingWatched extends java.util.Observable {
- void counter(int period) {
- for(; period<=0; period-- ) {
- setChanged();
- notifyObservers(new Integer(period));
- try {
- Thread.sleep(100);
- } catch( InterruptedException e) {
- System.out.println("Sleep interrupeted" );
- }
- }
- }
- };
測試
- publicclass ObserverDemo {
- publicstaticvoid main(String[] args) {
- BeingWatched beingWatched = new BeingWatched();//受查者
- Watcher watcher = new Watcher();//觀察者
- beingWatched.addObserver(watcher);
- beingWatched.counter(10);
- }
- }
原來這兩種api可以說都是基於:訂閱-釋出模式的事件/訊息通知模式,二者應該都算是“推”方式吧,就是被監控者將訊息通知給所有監控者。
1、訂閱:Observable.addObserver;
事件源.addDemoListener(這個方法是自己定義的)。
2、釋出:Observable需要兩步:setChanged()、notifyObservers(newValue); 事件源.notifyDemoEvent()(這個方法也是自己定義的)。