0
点赞
收藏
分享

微信扫一扫

观察者模式——监听与回调

两岁时就很帅 2022-02-23 阅读 42

观察者模式属于行为型模式。它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
在这里插入图片描述
Subject(抽象被观察者):抽象主题角色把所有观察者对象的引用保存在一个集合里,并提供可以增加和删除观察者的接口。

ConcreteSubject(具体被观察者):该角色接受具体观察者对象,并在具体主题的内部状态发生改变时,给所有观察者对象发出通知。

Observer(抽象观察者):它定义了一个更新接口,在被观察者发出通知的时候可以更新自己。

ConcreteObserver(具体观察者):实现抽象观察者定义的更新接口,当得到主题更改通知时更新自己。

import java.lang.reflect.Method;

/**
 * @Description: 监听器的一种包装,标准事件源格式的定义
 * @title: Event
 * @Author zhsun
 * @Date: 2022/2/23 21:20
 * @Version 1.0
 */
public class Event {

    // 事件源,事件是由谁发起的,保存起来
    private Object source;

    // 事件出发,要通知谁
    private Object target;

    // 事件出发,需要做什么动作,回调
    private Method callBack;

    // 事件的名称,触发的是什么事件
    private String trigger;

    // 事件的触发时间
    private long time;

    public Event(Object target, Method callBack) {
        this.target = target;
        this.callBack = callBack;
    }

    public Object getSource() {
        return source;
    }

    public Event setSource(Object source) {
        this.source = source;
        return this;
    }

    public Object getTarget() {
        return target;
    }

    public Event setTarget(Object target) {
        this.target = target;
        return this;
    }

    public Method getCallBack() {
        return callBack;
    }

    public void setCallBack(Method callBack) {
        this.callBack = callBack;
    }

    public String getTrigger() {
        return trigger;
    }

    public Event setTrigger(String trigger) {
        this.trigger = trigger;
        return this;
    }

    public long getTime() {
        return time;
    }

    public void setTime(long time) {
        this.time = time;
    }

    @Override
    public String toString() {
        return "Event{" +
                "source=" + source +
                ", target=" + target +
                ", callBack=" + callBack +
                ", trigger='" + trigger + '\'' +
                ", time=" + time +
                '}';
    }
}

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * @Description: 监听器,它就是观察者的桥梁
 * @title: EventLisenter
 * @Author zhsun
 * @Date: 2022/2/23 21:30
 * @Version 1.0
 */
public class EventLisenter {

    protected Map<String,Event> events = new HashMap<>();

    // 通过事件名称和一个目标对象来触发事件
    public void addLisenter(String eventType,Object target) {
        try {
            this.addLisenter(
                    eventType,
                    target,
                    target.getClass().getMethod("on"+toUpperFirstCase(eventType),Event.class)
            );
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public void addLisenter(String eventType, Object target, Method callBack) {
        // 注册事件
        events.put(eventType,new Event(target,callBack));
    }


    // 触发,只要有动作就触发
    private void trigger (Event event) {
        event.setSource(this);
        event.setTime(System.currentTimeMillis());
        try {
            // 发起回调
            if (event.getCallBack() != null) {
                // 反射调用其回调函数
                event.getCallBack().invoke(event.getTarget(),event);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 事件名称触发
    protected void trigger(String trigger) {
        if(!this.events.containsKey(trigger)) {
            return;
        }
        trigger(this.events.get(trigger).setTrigger(trigger));
    }

    // 逻辑处理的私有化方法,首字母大写
    private String toUpperFirstCase(String str) {
        char[] chars = str.toCharArray();
        chars[0] -=32;
        return String.valueOf(chars);
    }


}

/**
 * @Description:
 * @title: Mouse
 * @Author zhsun
 * @Date: 2022/2/23 22:22
 * @Version 1.0
 */
public class Mouse extends EventLisenter{

    public void click() {
        System.out.println("调用单击方法");
        this.trigger(MouseEventType.ON_CLICK);
    }

    public void doubleClick() {
        System.out.println("调用双击方法");
        this.trigger(MouseEventType.ON_DOUBLE_CLICK);
    }

    public void up() {
        System.out.println("调用弹起方法");
        this.trigger(MouseEventType.ON_UP);
    }

    public void down() {
        System.out.println("调用按下方法");
        this.trigger(MouseEventType.ON_DOWN);
    }

    public void move() {
        System.out.println("调用移动方法");
        this.trigger(MouseEventType.ON_MOVE);
    }

    public void wheel() {
        System.out.println("调用滚动方法");
        this.trigger(MouseEventType.ON_WHEEL);
    }

    public void over() {
        System.out.println("调用悬停方法");
        this.trigger(MouseEventType.ON_OVER);
    }

    public void blur() {
        System.out.println("调用获焦方法");
        this.trigger(MouseEventType.ON_BLUR);
    }

    public void focus() {
        System.out.println("调用失焦方法");
        this.trigger(MouseEventType.ON_FOCUS);
    }


}

/**
 * @Description:
 * @title: MouseEventType
 * @Author zhsun
 * @Date: 2022/2/23 21:25
 * @Version 1.0
 */
public interface MouseEventType {

    // 单击
    String ON_CLICK = "click";

    // 双击
    String ON_DOUBLE_CLICK = "doubleClick";

    // 弹起
    String ON_UP = "up";

    // 按下
    String ON_DOWN = "down";

    // 移动
    String ON_MOVE = "move";

    // 滚动
    String ON_WHEEL = "wheel";

    // 悬停
    String ON_OVER = "over";

    // 失焦
    String ON_BLUR = "blur";

    // 获焦
    String ON_FOCUS = "focus";

}

/**
 * @Description:
 * @title: MouseEventCallback
 * @Author zhsun
 * @Date: 2022/2/23 22:31
 * @Version 1.0
 */
public class MouseEventCallback {

    public void onClick(Event event) {
        System.out.println("===========触发鼠标单击事件==========" + "\n" + event);
    }

    public void onDoubleClick(Event event) {
        System.out.println("===========触发鼠标双击事件==========" + "\n" + event);
    }

    public void onUp(Event event) {
        System.out.println("===========触发鼠标弹起事件==========" + "\n" + event);
    }

    public void onDown(Event event) {
        System.out.println("===========触发鼠标按下事件==========" + "\n" + event);
    }

    public void onMove(Event event) {
        System.out.println("===========触发鼠标移动事件==========" + "\n" + event);
    }

    public void onWheel(Event event) {
        System.out.println("===========触发鼠标滚动事件==========" + "\n" + event);
    }

    public void onOver(Event event) {
        System.out.println("===========触发鼠标悬停事件==========" + "\n" + event);
    }

    public void onBlur(Event event) {
        System.out.println("===========触发鼠标失焦事件==========" + "\n" + event);
    }

    public void onFocus(Event event) {
        System.out.println("===========触发鼠标获焦事件==========" + "\n" + event);
    }
}

/**
 * @Description: 测试实现类
 * @title: Test
 * @Author zhsun
 * @Date: 2022/2/23 22:41
 * @Version 1.0
 */
public class Test {
    public static void main(String[] args) {
        try {
            MouseEventCallback callback = new MouseEventCallback();

            // 注册事件
            Mouse mouse = new Mouse();
            mouse.addLisenter(MouseEventType.ON_CLICK,callback);
            mouse.addLisenter(MouseEventType.ON_MOVE,callback);
            mouse.addLisenter(MouseEventType.ON_WHEEL,callback);
            mouse.addLisenter(MouseEventType.ON_OVER,callback);

            // 调用方法
            mouse.click();

            // 市焦事件
            mouse.blur();


        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

举报

相关推荐

0 条评论