当前位置:网站首页>Using function to realize observer mode

Using function to realize observer mode

2021-05-04 16:52:20 Jiedao jdon

The observer model is certainly one of the most common and widely used . The purpose is to allow one or more objects to be notified when an event occurs and act accordingly . The main abstraction of this pattern is Listener Interface :

interface Listener {
    void onEvent(Object event);
}

When on Object wants to be notified when an event occurs , Or to listen for events , It just implements this interface and onEvent() The body of the method encodes how it responds to the arrival of an event . It corresponds to a Observable object , Or to put it another way , An object notifies its registered listeners by sending them an event when the related event occurs .

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 );
        }
    }
}

In the introduction of lambdas Before , In this Observable Registered on Listener The two typical ways to do this are through anonymous inner classes :

public class Observer1 {
    Observer1(Observable observable) {
        observable.register( this, new Listener() {
            @Override
            public void onEvent( Object event ) {
                System.out.println(event);
            }
        } );
    }
}

Or make your object directly implement Listener Interface .

public class Observer2 implements Listener {
    Observer2(Observable observable) {
        observable.register( this, this );
    }
    @Override
    public void onEvent( Object event ) {
        System.out.println(event);
    }
}

Both observers can use... In the same way , When Observable When sending an event , It will be broadcast to :

Observable observable = new Observable();
new Observer1( observable );
new Observer2( observable );
observable.sendEvent( "Hello World!" );

However , These two solutions reveal once again GoF Frequently asked questions about the largest part of the pattern : They have to translate verbs and actions to be taken when the event arrives into nouns 、 Category 、 Anonymity or not packaging these behaviors . In order to take advantage of Java 8 New features of , The first thing to note is what we defined above Listener Interfaces are semantically equivalent to 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 ) );
    }
}

Besides , No longer need to use specific class implementations Listener, And you can use lambda The expression encodes the response to the arrival of the event , Or, in this case, code with a simpler method reference .

Observable observable = new Observable();
observable.register( "key1", e -> System.out.println(e) );
observable.register( "key2", System.out::println );
observable.sendEvent( "Hello World!" );

 

版权声明
本文为[Jiedao jdon]所创,转载请带上原文链接,感谢
https://chowdera.com/2021/05/20210504164657815m.html

随机推荐