概述
監聽器,在很多的源碼中都非常的常見,之后我會寫一個nacos源碼分析的文章,那里面也用了很多的監聽器,為什么要使用監聽器,舉個例子,大家在過紅綠燈的時候,每一個司機其實就是一個觀察者,那觀察的目標是什么呢?觀察的目標就是紅綠燈,那這個過程中會產生什么事件呢?就是紅燈,黃燈,綠燈的事件,當司機收到這些事件之后會做出不同的舉動。那如果不使用這種模式,就是我不用紅綠燈,我直接找個交警去一個司機一個司機通知,告訴每個司機,你可以走了,你不能走,比較一下大家就可以發現第一種方式效率更高。其實上面的紅綠燈的場景就是一個典型的監聽器模式,是23中設計模式中的一種,要想搞明白springboot中的監聽器原理,就要先搞清楚監聽器模式原理,所以本篇文章就先介紹設計模式之-監聽器模式。
監聽器模式核心組成部分
目標:這個很難解釋,我就把比較官方的話貼出來吧,大家看完例子之后回頭看看官方的定義,目標被觀察的對象,在目標中定義了一個觀察者集合,提供一系列方法可以增加或者刪除觀察者,同時定義了通知觀察者的方法,目標類可以是接口或者抽象類或者具體類。
具體目標:是目標類的字類
Observer:觀察者,對觀察目標的改變做出反應,觀察者一般定義為接口
ConcreteObserver:具體觀察者,和具體的目標狀態綁定
看這些概念很頭大,下面看一個具體的例子
觀察者
package com.example.demo.event; /** * @author steve * @date 2020/6/3 3:02 下午 */ public interface WeekendListener { public void onEvent(WeekendEvent event); }
具體觀察者
public class SleepListener implements WeekendListener{ @Override public void onEvent(WeekendEvent event) { if (event instanceof SleepEvent){ System.out.println("hello,"+event.getName()); } } }
具體觀察者
public class ShoppingListener implements WeekendListener{ @Override public void onEvent(WeekendEvent event) { if (event instanceof ShoppingEvent){ System.out.println("hello, "+event.getName()); } } }
事件
public class ShoppingEvent implements WeekendEvent{ @Override public String getName() { return "shopping"; } }
事件
public class SleepEvent implements WeekendEvent{ @Override public String getName() { return "sleep"; } }
目標
public abstract class AbstractEventtMulticaster { public List<WeekendListener> listeners ; public AbstractEventtMulticaster(List<WeekendListener> listeners){ this.listeners = new ArrayList<>(listeners); } public void multicaster(WeekendEvent event){ doStart(); listeners.stream().forEach(l -> l.onEvent(event)); doEnd(); } public void addListener(WeekendListener listener){ listeners.add(listener); } public void removeListener(WeekendListener listener){ listeners.remove(listener); } abstract public void doStart(); abstract public void doEnd(); }
具體目標
public class SimpleEventMulticaster extends AbstractEventtMulticaster{ public SimpleEventMulticaster(List<WeekendListener> listeners) { super(listeners); } @Override public void doStart() { System.out.println("start 搞事情"); } @Override public void doEnd() { System.out.println("end 搞事情"); } }
測試
public class Test { public static void main(String[] args) { ShoppingListener shoppingListener = new ShoppingListener(); SleepListener sleepListener = new SleepListener(); SimpleEventMulticaster simpleEventMulticaster = new SimpleEventMulticaster(new ArrayList<WeekendListener>()); simpleEventMulticaster.addListener(shoppingListener); simpleEventMulticaster.addListener(sleepListener); simpleEventMulticaster.multicaster(new ShoppingEvent()); simpleEventMulticaster.removeListener(shoppingListener); simpleEventMulticaster.multicaster(new ShoppingEvent()); } }
輸出結果:
start 搞事情
hello, shopping
end 搞事情
start 搞事情
end 搞事情
解釋:這里定義了觀察者WeekendListener,這個觀察者的作用就是觀察周末到底要干啥,然后定義了兩個具體觀察者,就是ShoppingListener和SleepListener,這兩個是具體觀察者,觀察這個人是睡覺還是去購物,然后就定義了兩種行為,也就是兩個事件SleepEvent和ShoppingEvent,這兩個事件就是具體的狀態,然后定義了目標就是AbstractEventtMulticaster,這個里面定義了觀察者的集合,定義了新增和刪除觀察者,同時還定義了一個關鍵的方法multicaster,這個方法會在出現具體的事件的時候,將事件廣播給每一個觀察者,然后執行回調onEvent()方法,其實在具體觀察者中可以定義interest()方法,這個方法的作用就是看這個具體的觀察者是不是對這個事件感興趣,如果感興趣就可以執行具體某個行為。
下一篇文章我會結合springboot源碼分析springboot是如何使用觀察者模式的。