使用函式式實現觀察者模式模式
觀察者模式肯定是最常見和最廣泛使用的模式之一。其目的是允許在某個事件發生時通知一個或多個物件並相應地採取行動。這種模式的主要抽象是Listener介面:
interface Listener { void onEvent(Object event); } |
當on物件想要在事件發生時得到通知,或者要監聽事件時,它只需實現此介面並在onEvent()方法的主體中編碼它如何對事件的到達作出反應。對應的是一個Observable物件,或者換句話說,一個物件透過在相關事件發生時向它們傳送事件來通知其註冊的偵聽器。
public class Observable { private final Map<Object, Listener> listeners = new ConcurrentHashMap<>(); public void register(Object key, Listener listener) { listeners.put(key, listener); } public void unregister(Object key) { listeners.remove(key); } public void sendEvent(Object event) { for (Listener listener : listeners.values()) { listener.onEvent( event ); } } } |
在引入lambdas之前,在這個Observable上註冊Listener的兩種典型方法是透過匿名內部類:
public class Observer1 { Observer1(Observable observable) { observable.register( this, new Listener() { @Override public void onEvent( Object event ) { System.out.println(event); } } ); } } |
或使您的物件直接實現Listener介面。
public class Observer2 implements Listener { Observer2(Observable observable) { observable.register( this, this ); } @Override public void onEvent( Object event ) { System.out.println(event); } } |
這兩個觀察者都可以以相同的方式使用,當Observable傳送一個事件時,它將被廣播到:
Observable observable = new Observable(); new Observer1( observable ); new Observer2( observable ); observable.sendEvent( "Hello World!" ); |
然而,這兩個解決方案再一次揭示了GoF模式最大部分的常見問題:它們必須將動詞以及事件到達時要採取的行動轉換為名詞、類別、匿名或不包裝這些行為。為了利用Java 8的新功能特性,首先要注意的是我們上面定義的Listener介面在語義上等同於Consumer:
public class Observable { private final Map<Object, Consumer<Object>> listeners = new ConcurrentHashMap<>(); public void register(Object key, Consumer<Object> listener) { listeners.put(key, listener); } public void unregister(Object key) { listeners.remove(key); } public void sendEvent(Object event) { listeners.values().forEach( listener -> listener.accept( event ) ); } } |
此外,不再需要使用特定類實現Listener,並且可以使用lambda表示式對事件到達的反應進行編碼,或者在這種情況下也使用更簡潔的方法引用進行編碼。
Observable observable = new Observable(); observable.register( "key1", e -> System.out.println(e) ); observable.register( "key2", System.out::println ); observable.sendEvent( "Hello World!" ); |
相關文章
- Java設計模式-回撥函式和觀察者模式Java設計模式函式
- 使用函式式方式實現責任鏈模式函式模式
- 設計模式學習-使用go實現觀察者模式設計模式Go
- JS原生實現觀察者模式JS模式
- JavaScript原生實現觀察者模式JavaScript模式
- 設計模式(python實現):觀察者模式設計模式Python
- 觀察者模式在One Order回撥函式中的應用模式函式
- Go 實現常用設計模式(五)觀察者模式Go設計模式
- javascript中的觀察者模式實現JavaScript模式
- 如何使用 Java8 實現觀察者模式?(下)Java模式
- 設計模式實戰 - 觀察者模式設計模式
- 設計模式實踐--觀察者模式設計模式
- 用Map+函式式介面來實現策略模式函式模式
- iOS使用觀察者模式實現推送訊息模組化iOS模式
- 原生實現的觀察者模式(Observer Model)模式Server
- PHP實現觀察者模式SplSubject SplObserver SplObjectStoragePHP模式ServerObject
- JS 利用高階函式實現函式快取(備忘模式)JS函式快取模式
- 實驗 21:觀察者模式模式
- 觀察者模式模式
- 『設計模式』高階函式實現 AOP設計模式函式
- 三種觀察者模式的C#實現模式C#
- 設計模式----觀察者模式設計模式
- 設計模式 —— 觀察者模式設計模式
- 設計模式(觀察者模式)設計模式
- 設計模式——觀察者模式設計模式
- 設計模式-觀察者模式設計模式
- 設計模式_觀察者模式設計模式
- 【設計模式】觀察者模式設計模式
- 用函式正規化實現戰略模式函式模式
- PHP觀察者模式PHP模式
- Unity——觀察者模式Unity模式
- 觀察者模式(2)模式
- Java 觀察者模式Java模式
- JS 觀察者模式JS模式
- 設計模式(十六)觀察者模式設計模式
- 行為型模式:觀察者模式模式
- PHP設計模式-觀察者模式PHP設計模式
- 設計模式(9) 觀察者模式設計模式