【Design Patterns】監聽器模式

監聽器模式

監聽器模式實際上是觀察者模式中的一種,二者都有關於回調的設計。java

與觀察者模式不一樣的是,觀察者模式中存在的角色爲觀察者(Observer)被觀察者(Observable)ide

而監聽器模式中存在三種角色函數

  • 事件源(EventSource)
  • 事件對象(EventObject)
  • 事件監聽器(EventListener)

簡單的概述就是: 事件源通過事件的封裝傳給監聽器,當事件源觸發事件後,監聽器接收到事件對象能夠回調事件的方法this

下面這張圖能夠很詳細解釋他們之間的關係設計

簡單的實例

UML3d

@startuml
class EventSource{
- listeners: Vector<EventListener>
+ void addListener(EventListener listener)
+ void removeListener(EventListener listener)
+ void notifyListenerEvents(EventObject eventObject)
}

class EventObject{
+ getSource(): Object
+ void:say()

}

interface EventListener{
+ void handleEvent(EventObject eventObject)
}

class ConcreteEvetListenerA{
+ void handleEvent(EventObject eventObject)
}
class ConcreteEvetListenerB{
+ void handleEvent(EventObject eventObject)
}

EventListener <-- ConcreteEvetListenerA
EventListener <-- ConcreteEvetListenerB


EventObject --o EventListener

EventSource -- EventObject
@enduml

事件源

public class DemoEventSource {

    /** 監聽器列表 */
    public Vector<DemoEventListener> listeners = new Vector<>();

    /**
     * 註冊監聽器
     * @param listener EventListener
     */
    public void addListener(DemoEventListener listener) {
        listeners.add(listener);
    }

    /**
     * 撤銷監聽器
     * @param listener EventListener
     */
    public void removeListener(DemoEventListener listener) {
        listeners.remove(listener);
    }


    /**
     * 通知全部監聽器,包裹事件源成爲事件
     * @param eventObject EventObject
     */
    public void notifyListenerEvents(EventObject eventObject){
        listeners.forEach(listener ->{
            listener.handleEvent(eventObject);
        });
    }
}

事件對象

public class DemoEventObject extends EventObject {

    /**
     * Constructs a prototypical Event.
     *
     * @param source The object on which the Event initially occurred.
     * @throws IllegalArgumentException if source is null.
     */
    public DemoEventObject(Object source) {
        super(source);
    }


    /**
     * 事件的回調或者業務邏輯
     */
    public void say() {
        System.out.println("this is " + this + " to say");
    }
}

事件監聽器

public interface DemoEventListener extends EventListener {

    /**
     * 處理事件
     * @param eventObject EventObject
     */
    void handleEvent(EventObject eventObject);
}

public class ConcreteEventListenerA implements DemoEventListener {

    @Override
    public void handleEvent(EventObject eventObject) {
        System.out.println("ConcreteEventListenerA accept eventObject , eventSource is : " + eventObject.getSource());
        if (eventObject instanceof DemoEventObject) {
            // 執行事件的回調函數/具體業務邏輯
            ((DemoEventObject) eventObject).say();
        }
    }
}

public class ConcreteEventListenerB implements DemoEventListener {

    @Override
    public void handleEvent(EventObject eventObject) {
        System.out.println("ConcreteEventListenerB accept eventObject , eventSource is : " + eventObject.getSource());

        if (eventObject instanceof DemoEventObject) {
            // 執行事件的回調函數/具體業務邏輯
            ((DemoEventObject) eventObject).say();
        }

    }
}

客戶端

public class Client {
    public static void main(String[] args) {

        // 初始化監聽器
        DemoEventListener demoEventListenerA = new ConcreteEventListenerA();
        DemoEventListener demoEventListenerB = new ConcreteEventListenerB();

        // 事件源A
        DemoEventSource demoEventSource1 = new DemoEventSource();
        demoEventSource1.addListener(demoEventListenerA);
        demoEventSource1.addListener(demoEventListenerB);
        demoEventSource1.notifyListenerEvents(new DemoEventObject(demoEventSource1));

        // 事件源B
        DemoEventSource demoEventSource2 = new DemoEventSource();
        demoEventSource2.addListener(demoEventListenerB);
        demoEventSource2.notifyListenerEvents(new DemoEventObject(demoEventSource2));
    }
}
相關文章
相關標籤/搜索