设计模式九 观察者模式

0、基本定义

定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则全部依赖于它的对象都会获得通知并被自动更新。ide

发布者/订阅者模式。this

 

事件监听、swing中都有用到。spa

一、代码实战

时间核心类日志

/**
 * 事件
 * @author zzf
 * @date 2018/9/2 15:30.
 */
public class Event {

    //source
    private Object source;
    //target
    private Object target;
    //callback
    private Method callback;

    //触发事件
    private String trigger;

    private long timestamp;

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

    public long getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(long timestamp) {
        this.timestamp = timestamp;
    }

    public Object getTarget() {
        return target;
    }

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

    public Method getCallback() {
        return callback;
    }

    public void setCallback(Method callback) {
        this.callback = callback;
    }

    public Object getSource() {
        return source;
    }

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

    public String getTrigger() {
        return trigger;
    }

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

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

    //至关注册器
    protected Map<Enum, Event> events = new HashMap<>();

    public void addListener(Enum eventType, Object taget, Method callback)  {
        //注册事件
        //反射调用
        events.put(eventType, new Event(taget, callback));

    }

    private void trigger(Event e) {
        e.setSource(this);
        e.setTimestamp(System.currentTimeMillis());

        try {

            e.getCallback().invoke(e.getTarget(), e);
        } catch (Exception e1) {

        }
    }

    protected void trigger(Enum call) {
        if (!this.events.containsKey(call)) {
            return;
        }

        trigger(this.events.get(call).setTrigger(call.toString()));
     }
}

 

观察者code

/**
 * 观察者
 * @author zzf
 * @date 2018/9/2 15:29.
 */
public class Observer {

    public void advice(Event event) {
        System.out.println("====== 触发事件,打印日志====\n" + event);
    }
}

被观察者视频

/**
 * 被观察者
 * @author zzf
 * @date 2018/9/2 15:28.
 */
public class Subject extends EventListener {

    //一般采用动态里实现监控,避免代码侵入
    public void add() {
        System.out.println("add()");
        trigger(SubjectEventType.ON_ADD);
    }

    public void remove() {
        System.out.println("remove()");
        trigger(SubjectEventType.ON_RMOVE);
    }
}

public enum SubjectEventType {
ON_ADD,
ON_RMOVE,
ON_EDIT,
ON_QUERY;
}
 

testserver

public class ObserverTest {

    public static void main(String[] args) {

        try {

            //观察者和被观察者没有必然的联系
            //注册的时候,才产生联系
            Observer observer = new Observer();
            Method advice = Observer.class.getMethod("advice", new Class[]{Event.class});


            Subject subject = new Subject();

            //添加监听
            subject.addListener(SubjectEventType.ON_ADD, observer, advice);

            subject.add();
            subject.remove();

        } catch (Exception e) {

        }
    }
}

 

二、使用场景

》关联行为场景对象

》事件多级触发场景blog

》跨系统的消息交换场景,如消息队列的处理机制。队列

三、总结

这是听咕泡学院视频的实战笔记。和书上的标准模式demo 相差仍是蛮大的。

 

本身感受能看懂,可是在实际中应用仍是有点懵。

 

参考资料:

咕泡学院