zoukankan      html  css  js  c++  java
  • JAVA设计模式—观察者模式Observer的演变

    观察者模式基础

    以下是小孩哭这个动作,通知所观察者(Mum Dad Dog)做出不同的反应

    /**
     * 分离观察者与被观察者
     */
    
    class Child {
        private boolean cry = false;
        private List<Observer> observers = new ArrayList<>();
    
        {
            observers.add(new Dad());
            observers.add(new Mum());
            observers.add(new Dog());
        }
    
    
        public boolean isCry() {
            return cry;
        }
    
        public void wakeUp() {
            cry = true;
            for(Observer o : observers) {
                o.actionOnWakeUp();
            }
        }
    }
    /**定义主题对象接口 观察者接口**/
    interface Observer {
        void actionOnWakeUp();
    }
    
    class Dad implements Observer {
        public void feed() {
            System.out.println("dad feeding...");
        }
    
        @Override
        public void actionOnWakeUp() {
            feed();
        }
    }
    
    class Mum implements Observer {
        public void hug() {
            System.out.println("mum hugging...");
        }
    
        @Override
        public void actionOnWakeUp() {
            hug();
        }
    }
    
    class Dog implements Observer {
        public void wang() {
            System.out.println("dog wang...");
        }
    
        @Override
        public void actionOnWakeUp() {
            wang();
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            Child c = new Child();
            //do sth
            c.wakeUp();
        }
    }

    dad feeding...
    dog wang...
    mum hugging...

    观察者模式本身比较简单 就是多态的应用

    很多时候 观察者需要根据这件事的具体情况做出相应的处理:比如小孩哭的时间和地点,观察者做出的反应应该不同

    下面对观察者模式进行进一步的封装

    抽象出处理事件类

    把小孩哭得所有状况传到一个事件里面

    //事件类 fire Event
    class wakeUpEvent{
        long timestamp;
        String loc;
    
        public wakeUpEvent(long timestamp, String loc) {
            this.timestamp = timestamp;
            this.loc = loc;
        }
    }
    
    interface Observer {
        void actionOnWakeUp(wakeUpEvent event);
    }

    有点类似发布订阅,发布者发布一个事件,订阅者接收这个事件

    事件类增加事件源对象,并形成继承体系

    大多数时候,我们处理事件的时候,需要事件源对象(有时观察者需要事件原对象的一些资源)

    class wakeUpEvent{
        long timestamp;
        String loc;
        Child source;
    
        public wakeUpEvent(long timestamp, String loc, Child source) {
            this.timestamp = timestamp;
            this.loc = loc;
            this.source = source;
        }
    }

    因为我们都是面向接口编程 所以把事件定义一个接口或者抽象类。这也是多态的应用

    abstract class Event<T> {
        abstract T getSource();
    }
    
    class wakeUpEvent extends Event<Child>{
        long timestamp;
        String loc;
        Child source;
    
        public wakeUpEvent(long timestamp, String loc, Child source) {
            this.timestamp = timestamp;
            this.loc = loc;
            this.source = source;
        }
    
        @Override
        Child getSource() {
            return source;
        }
    }

    其实Observer Listener Hook CallBack 这些都是观察者模式

    最终代码

    package com.mashibing.dp.observer.v8;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 有很多时候,观察者需要根据事件的具体情况来进行处理
     * 大多数时候,我们处理事件的时候,需要事件源对象
     * 事件也可以形成继承体系
     */
    
    class Child {
        private boolean cry = false;
        private List<Observer> observers = new ArrayList<>();
    
        {
            observers.add(new Dad());
            observers.add(new Mum());
            observers.add(new Dog());
            observers.add((e)->{
                System.out.println("ppp");
            });
            //hook callback function
        }
    
    
        public boolean isCry() {
            return cry;
        }
    
        public void wakeUp() {
            cry = true;
    
            wakeUpEvent event = new wakeUpEvent(System.currentTimeMillis(), "bed", this);
    
            for(Observer o : observers) {
                o.actionOnWakeUp(event);
            }
        }
    }
    
    abstract class Event<T> {
        abstract T getSource();
    }
    
    class wakeUpEvent extends Event<Child>{
        long timestamp;
        String loc;
        Child source;
    
        public wakeUpEvent(long timestamp, String loc, Child source) {
            this.timestamp = timestamp;
            this.loc = loc;
            this.source = source;
        }
    
        @Override
        Child getSource() {
            return source;
        }
    }
    
    interface Observer {
        void actionOnWakeUp(wakeUpEvent event);
    }
    
    class Dad implements Observer {
        public void feed() {
            System.out.println("dad feeding...");
        }
    
        @Override
        public void actionOnWakeUp(wakeUpEvent event) {
            feed();
        }
    }
    
    class Mum implements Observer {
        public void hug() {
            System.out.println("mum hugging...");
        }
    
        @Override
        public void actionOnWakeUp(wakeUpEvent event) {
            hug();
        }
    }
    
    class Dog implements Observer {
        public void wang() {
            System.out.println("dog wang...");
        }
    
        @Override
        public void actionOnWakeUp(wakeUpEvent event) {
            wang();
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            Child c = new Child();
            //do sth
            c.wakeUp();
        }
    }
    View Code

    ApplicationListener

    Spring中的ApplicationListener也是使用的观察者模式,下面两种方式做比较

    https://www.cnblogs.com/ssskkk/p/12942375.html#_label4

  • 相关阅读:
    InfoPath 发布表单到SharePoint库报错
    在log4net中控制nhibernate输出
    微信扫一扫(wx.scanQRCode)功能新手可能遇到的问题
    3.Zookeeper的安装和配置(集群模式)
    1.配置HDFS HA (高可用)
    2.Zookeeper工作原理(详细)
    1.Zookeeper 定义与工作原理
    js 获取元素的几种方法
    弹出层居中
    XUACompatible
  • 原文地址:https://www.cnblogs.com/ssskkk/p/9703926.html
Copyright © 2011-2022 走看看