JAVA另类观察者模式- 类似Flex AS的 事件机制 (事件监听、事件移除、以及事件抛出)

老规矩了,本文所有代码在我的公网jar  OwlMagicComment中都能寻到

如果你只是想快速使用,那么引用方式如下

<!-- https://mvnrepository.com/artifact/com.github.engwen/owlMagicComment -->
<dependency>
    <groupId>com.github.engwen</groupId>
    <artifactId>owlMagicComment</artifactId>
    <version>1.1.8</version>
</dependency>


如果使用代码请标注来源,谢谢!!!!

gitHub源码地址:https://github.com/engwen/owlMagicComment/blob/master/readMeCn.md

基本思路如下:

1:需要事件 -> 新建一个基本事件类型作为  监听  抛出 的event

2:需要有基本的监听事件,移除事件,在监听到事件的时候执行指定代码 -->新建一个抽象类,这个抽象需要集成一个记忆功能(这里使用的Map<event,待执行代码>对象),能够添加监听事件,并在监听到事件之后执行,另外还需要移除监听的事件。这样在有想要使用这个功能的类上直接继承这个类便可以拥有以上功能

3:需要有一个扩展类,这个类用来记录所有的事件下,各个监听对象和事件之间的关系(使用Map<event,Set>记录),提供能直接操作监听对象的功能-》比如移除全部监听事件,移除指定类型的全部监听事件等等

代码如下

package com.owl.observer;

/**
 * @author engwen
 * email xiachanzou@outlook.com
 * 2019/4/26.
 */
public class OwlObserverEvent {
    private String eventName;

    public OwlObserverEvent(String eventName) {
        this.eventName = eventName;
    }

    public static OwlObserverEvent DEFAULT_EVENT = new OwlObserverEvent("默认事件");


    public String getEventName() {
        return eventName;
    }

    public void setEventName(String eventName) {
        this.eventName = eventName;
    }
}

 

 

package com.owl.observer;

import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;

/**
 * 被观察者抽象
 * @author engwen
 * email xiachanzou@outlook.com
 * 2019/4/26.
 */
public abstract class OwlObserved {

    private Map<String, Consumer<OwlObserved>> consumerMap = new HashMap<>();

    //被觀察者監聽事件
    public void addEventListen(OwlObserverEvent event, Consumer<OwlObserved> consumer) {
        //添加事件处理方法记录
        consumerMap.put(event.getEventName(), consumer);
        //注冊驅動
        OwlObserverAB.addEventListen(event, this);
    }

    public void removeListen(OwlObserverEvent event) {
        OwlObserverAB.removeEventListen(event, this);
    }

    //抛出
    public void dispatchEvent(OwlObserverEvent owlObserverEvent) {
        OwlObserverAB.dispatchEvent(owlObserverEvent);
    }

/*------------------           以下方法提供給 OwlObserverAB 用於數據同步/脚本執行           ---------------------*/
    //移除指定事件
    void removeListenByEvent(OwlObserverEvent event) {
        if (null != consumerMap.get(event.getEventName())) {
            consumerMap.remove(event.getEventName());
        }
    }

    //移除所有事件
    void removeAllListen() {
        consumerMap = null;
        consumerMap = new HashMap<>();
    }

    //被觀察者需要执行的代碼
    void startDoing(OwlObserverEvent event) {
        Consumer<OwlObserved> consumer = consumerMap.get(event.getEventName());
        if (null != consumer) {
            //執行
            consumer.accept(this);
        }
    }
}
package com.owl.observer;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Predicate;
import java.util.logging.Logger;

/**
 * 观察者抽象
 * @author engwen
 * email xiachanzou@outlook.com
 * 2019/4/26.
 */
public abstract class OwlObserverAB {
    private static Logger logger = Logger.getLogger(OwlObserverAB.class.getName());
    private static Map<String, Set<OwlObserved>> mapList = new HashMap<>();

    //添加对象监听
    static void addEventListen(OwlObserverEvent owlObserverEvent, OwlObserved model) {
        //監聽對象注冊
        mapList.putIfAbsent(owlObserverEvent.getEventName(), new HashSet<>());
        mapList.get(owlObserverEvent.getEventName()).add(model);
    }

    //移除監聽
    public static void removeEventListen(OwlObserverEvent owlObserverEvent, OwlObserved model) {
        removeEventList(owlObserverEvent, obj -> model == obj);
    }

    //移除監聽
    public static void removeEventListen(OwlObserverEvent owlObserverEvent, Class classModel) {
        removeEventList(owlObserverEvent, obj -> classModel.equals(obj.getClass()));
    }

    private static void removeEventList(OwlObserverEvent owlObserverEvent, Predicate<OwlObserved> predicate) {
        logger.info("移除事件监听:" + owlObserverEvent.getEventName());
        if (!mapList.keySet().contains(owlObserverEvent.getEventName())) {
            return;
        }
        AtomicReference<OwlObserved> temp = new AtomicReference<>();
        mapList.get(owlObserverEvent.getEventName()).forEach(it -> {
            if (predicate.test(it)) {
                it.removeListenByEvent(owlObserverEvent);
                temp.set(it);
            }
        });
        mapList.get(owlObserverEvent.getEventName()).remove(temp.get());
    }

    //移除監聽
    public static void removeEventListen(OwlObserverEvent owlObserverEvent) {
        logger.info("移除指定事件的全部监听:" + owlObserverEvent.getEventName());
        if (!mapList.keySet().contains(owlObserverEvent.getEventName())) {
            return;
        }
        mapList.get(owlObserverEvent.getEventName()).forEach(it -> it.removeListenByEvent(owlObserverEvent));
        mapList.remove(owlObserverEvent.getEventName());
    }

    //移除監聽
    public static void removeAllEventListen(OwlObserved model) {
        logger.info(String.format("移除%s的全部事件监听", model.getClass().getName()));
        mapList.keySet().forEach(key ->
                mapList.get(key).forEach(owlObserved -> {
                    if (owlObserved == model) {
                        mapList.get(key).remove(owlObserved);
                    }
                })
        );
        model.removeAllListen();
    }

    //抛出
    public static void dispatchEvent(OwlObserverEvent owlObserverEvent) {
        dispatchEvent(owlObserverEvent, obj -> true);
    }

    //抛出
    public static void dispatchEvent(OwlObserverEvent owlObserverEvent, Class classModel) {
        dispatchEvent(owlObserverEvent, obj -> obj.getClass().equals(classModel));
    }

    private static void dispatchEvent(OwlObserverEvent owlObserverEvent, Predicate<OwlObserved> predicate) {
        logger.info("抛出事件监听:" + owlObserverEvent.getEventName());
        if (null != mapList.get(owlObserverEvent.getEventName())) {
            mapList.get(owlObserverEvent.getEventName()).forEach(it -> {
                if (predicate.test(it)) {
                    it.startDoing(owlObserverEvent);
                }
            });
        }
    }
}

 

 

使用测试如下:

新建类继承被观察者

import com.owl.observer.OwlObserved;
import com.owl.observer.OwlObserverEvent;

import java.util.function.Consumer;

/**
 * @author engwen
 * email xiachanzou@outlook.com
 * 2019/6/10.
 */
public class TestOb extends OwlObserved {
    //被觀察者需要执行的代碼
    public static Consumer listenIng() {
       return  (obj)-> System.out.println("hhhhhhh");
    }

    //被觀察者需要执行的代碼
    public Consumer<OwlObserved> SystemOutYYYYY() {
        //做你想做的一切。别忘记本包中的 SpringContextUtil 可以在这里帮你获取 bean 哦
        return  (obj)-> System.out.println("yyyyyyyy");
    }

    //被觀察者需要执行的代碼
    public Consumer<OwlObserved> SystemOutHHHH() {
        //做你想做的一切。别忘记本包中的 SpringContextUtil 可以在这里帮你获取 bean 哦
        return  (obj)-> System.out.println("hhhhhhh");
    }
}


验证:
@Test
public void test() {
    TestOb testOb = new TestOb();
    OwlObserverEvent yyy = new OwlObserverEvent("SystemOutYYYYY");
    OwlObserverEvent hhh = new OwlObserverEvent("SystemOutHHHH");
    testOb.addEventListen(yyy, testOb.SystemOutYYYYY());
    testOb.addEventListen(hhh, testOb.SystemOutHHHH());
    OwlObserverAB.dispatchEvent(yyy, testOb.getClass());
    testOb.dispatchEvent(hhh);
    testOb.removeListen(yyy);
    OwlObserverAB.dispatchEvent(yyy);
    testOb.addEventListen(yyy, testOb.SystemOutYYYYY());
    OwlObserverAB.removeEventListen(yyy,testOb);
    OwlObserverAB.dispatchEvent(yyy);
}

 

 

结果
六月 17, 2019 4:47:44 下午 com.owl.observer.OwlObserverAB dispatchEvent
信息: 抛出事件监听:SystemOutYYYYY
yyyyyyyy
六月 17, 2019 4:47:44 下午 com.owl.observer.OwlObserverAB dispatchEvent
信息: 抛出事件监听:SystemOutHHHH
hhhhhhh
六月 17, 2019 4:47:44 下午 com.owl.observer.OwlObserverAB removeEventList
信息: 移除事件监听:SystemOutYYYYY
六月 17, 2019 4:47:44 下午 com.owl.observer.OwlObserverAB dispatchEvent
信息: 抛出事件监听:SystemOutYYYYY
六月 17, 2019 4:47:44 下午 com.owl.observer.OwlObserverAB removeEventList
信息: 移除事件监听:SystemOutYYYYY
六月 17, 2019 4:47:44 下午 com.owl.observer.OwlObserverAB dispatchEvent
信息: 抛出事件监听:SystemOutYYYYY
Disconnected from the target VM, address: '127.0.0.1:54024', transport: 'socket'

Process finished with exit code 0
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值