设计模式之观察者模式(行为型,做了一个动作,然后通知大家)

介绍

标准定义: (Observer Pattern)当对象间存在一对多关系时,则使用观察者模式。比如,当一个对象被修改时,则会自动通知它的依赖对象。观察者模式属于行为型模式。
通俗理解1:一般存在一对多的关系,如:老师在讲台上讲课,下面的同学在认真听讲。这时老师突然问同学们牛顿第一定律是什么,然后下面的同学认真的在思考,这就是一个观察者模式。老师是目标对象,同学们都是观察者。
通俗理解2:有一个微信公众号服务,不定时发布一些消息,关注公众号就可以收到推送消息,取消关注就收不到推送消息。

案例

场景:我们的鼠标有很多的事件,如:单击、双击、弹起、按下等。这些事件都在监听着鼠标的一举一动,这也是一个观察者模式。(事件监听器)
代码:
1》既然是事件监听器,那么先来一个事件类Event

//事件类
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 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 String getTrigger() {
        return trigger;
    }
    public Long getTime() {
        return time;
    }
    Event setTime(Long time) {
        this.time = time;
        return this;
    }
    @Override
    public String toString() {
        return "Event{" +
                "\n\tsource=" + source + ",\n" +
                "\ttarget=" + target + ",\n" +
                "\tcallback=" + callback + ",\n" +
                "\ttrigger='" + trigger + '\'' + "\n" +
                '}';
    }
    Event setSource(Object source) {
        this.source = source;
        return this;
    }
    Event setTrigger(String trigger) {
        this.trigger = trigger;
        return this;
    }
}

2》再来一个事件监听器

public class EventLisener {
    //map集合用来保存所有注册的事件
    protected Map<Enum,Event> events=new HashMap<Enum,Event>();

    public void addLisener(Enum eventType, Object target, Method callback){
        //注册事件
        //用反射调用这个方法
        events.put(eventType,new Event(target,callback));
;    }
    //将目标对象的行为保存下来(老师问同学们牛顿第一定律是什么?这是老师发出的行为)
    private void trigger(Event event){
        try {
            event.setSource(this);
            event.setTime(System.currentTimeMillis());
            event.getCallback().invoke(event.getTarget(),event);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    protected void trigger(Enum call){
        //判断这个目标对象的行为有没有被注册
        if(!events.containsKey(call)){
            return;
        }
        triigger(events.get(call).setTrigger(call.toString()));
    }
}

3》既然是鼠标(目标类)发出某种事件,那么来一个鼠标类继承事件监听类,这样鼠标发出的一些行为就能够被监听器监听到

public class Mouse extends EventLisener{
    public void click(){
        System.out.println("鼠标单击事件");
        trigger(MouseEventType.ON_CLICK);
    }
    public void dbClick(){
        System.out.println("鼠标双击事件");
        trigger(MouseEventType.ON_DOUBLE_CLICK);
    }
    public void up(){
        System.out.println("鼠标弹起事件");
        trigger(MouseEventType.ON_UP);
    }
    public void down(){
        System.out.println("鼠标按下事件");
        trigger(MouseEventType.ON_DOWN);
    }
}

4》再来一系列的观察者,来响应鼠标的行为

public class MouseEventCallback {
    public void click(Event event){
        System.out.println("=========鼠标单击事件========\n"+event);
    }
    public void dbClick(Event event){
        System.out.println("=========鼠标双击事件========\n"+event);
    }
    public void up(Event event){
        System.out.println("=========鼠标弹起事件========\n"+event);
    }
    public void down(Event event){
        System.out.println("=========鼠标按下事件========\n"+event);
    }
}

5》事件的枚举类

public enum  MouseEventType {
    ON_CLICK,
    ON_DOUBLE_CLICK,
    ON_UP,
    ON_DOWN;
}

6》鼠标开始发出单击的事件行为

public class MouseTest {

    public static void main(String[] args) {

        try {
            //一系列观察者
            MouseEventCallback mouseEventCallback=new MouseEventCallback();
            Method onClick=MouseEventCallback.class.getMethod("click", Event.class);

            //人为的调用鼠标的单击事件(目标)
            Mouse mouse=new Mouse();
            //给鼠标绑定单击事件
            mouse.addLisener(MouseEventType.ON_CLICK,mouseEventCallback,onClick);
            mouse.click();    
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
//            执行结果:
//            鼠标单击事件
//                    =========鼠标单击事件========
//            Event{
//                source=com.taofut.sjms.observer.mouse.Mouse@7f31245a,
//                        target=com.taofut.sjms.observer.mouse.MouseEventCallback@6d6f6e28,
//                        callback=public void com.taofut.sjms.observer.mouse.MouseEventCallback.click(com.taofut.sjms.observer.core.Event),
//                        trigger='ON_CLICK'
//            }
}

总结:生活中观察者模式的例子还有很多,监听器、短信通知、邮件通知等。观察者模式注重的是松耦合,观察者跟被观察者分离开来,两者之间没有必然的联系,所以不管是哪一方变化,都不会影响到另外一方。

猜你喜欢

转载自blog.csdn.net/fu123123fu/article/details/80201606