zoukankan      html  css  js  c++  java
  • 观察者模式(Observer Pattern)

    观察者模式:定义了对象间的一种一对多依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。
    image.png

    应用场景

    • Spring的Event监听
    • 订单成功后的邮件短信及活动发放
    • 分布式配置中心刷新配置
    • Zookeeper事件通知节点
    • 消息订阅通知
    • 安卓开发事件注册

    JDK自带的观察者

    Jdk中Observable 与ObServer区别
    ObServer是观察者,Observable是被观察者,也称之为主题。
    被观察者发生变化时通知观察者,观察者会跟着变动。

    /**
     * 观察者
     */
    public class EmailObServer implements Observer {
    
        public void update(Observable o, Object arg) {
            // 1.获取主题
            MessageObServable messageObServable = (MessageObServable) o;
            System.out.println("发送邮件内容:" + arg);
        }
    }
    
    /**
     * 被观察者
     */
    public class MessageObServable extends Observable {
    
        @Override
        public void notifyObservers(Object arg) {
            // 1.改变数据
            setChanged();
            // 2.通知所有的观察者改变
            super.notifyObservers(arg);
        }
    }
    
    /**
     * 测试代码
     *
     */
    public class JdkObServer {
        public static void main(String[] args) {
            //1.创建主题
            MessageObServable messageObServable = new MessageObServable();
            // 2.添加订阅者
            messageObServable.addObserver(new EmailObServer());
            messageObServable.addObserver(new SmsObServer());
            // 3.组装消息内容
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("email", "12345678@qq.com");
            jsonObject.put("phone", "13012341234");
            messageObServable.notifyObservers(jsonObject.toJSONString());
        }
    }
    

    Spring的Event监听

    //邮件观察者
    @Component
    public class EmailListener implements ApplicationListener<OrderCreateEvent> {
        @Override
        @Async
        public void onApplicationEvent(OrderCreateEvent event) {
            System.out.println(Thread.currentThread().getName()+"发送邮件内容:" + event.getJsonObject().toJSONString());
        }
    }
    
    //被观察者
    public class OrderCreateEvent extends ApplicationEvent {
        private JSONObject jsonObject;
    
        public OrderCreateEvent(Object source, JSONObject jsonObject) {
            super(source);
            this.jsonObject = jsonObject;
        }
    }
    
    /测试代码,利用上下文自动监听通知
    @RestController
    public class TestController {
        @Autowired
        private ApplicationContext applicationContext;
    
        @RequestMapping("/addOrder")
        public String addOrder() {
            System.out.println("创建订单...");
            // 3.组装消息内容
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("email", "123456@qq.com");
            jsonObject.put("phone", "13012341234");
            OrderCreateEvent orderCreateEvent = new OrderCreateEvent(this, jsonObject);
            applicationContext.publishEvent(orderCreateEvent);
            return "success";
        }
    }
    

    纯手写核心代码

    /**
     * 自动注册我们观察者
     *
     * 1.使用Spring获取该ObServer下有那些bean对象
     * 2.直接注添加到集合中
     *
     */
    //根据接口类型返回相应的所有bean
    Map<String, ObServer> map = applicationContext.getBeansOfType(ObServer.class);
    for (String key : map.keySet()) {
        ObServer obServer = map.get(key);
        jaryeSubject.addObServer(obServer);
    }
    
    /**
     * 新增ObServer
     *
     * @param obServer
     */
    public void addObServer(ObServer obServer) {
        listObServer.add(obServer);
    }
    
    /**
     * 通知给所有的观察者
     *
     * @param jsonObject
     */
    public void notifyObServer(JSONObject jsonObject) {
        for (ObServer obServer :
                listObServer) {
            // 单独开启线程异步通知
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    obServer.sendMsg(jsonObject);
                }
            });
    
        }
    }
    

    相关文章链接:
    <<<23中常用设计模式总览
    <<<代理模式(Proxy Pattern)
    <<<装饰模式(Decorator Pattern)
    <<<观察者模式(Observer Pattern)
    <<<单例模式(Singleton Pattern)
    <<<责任链模式(Chain of Responsibility Pattern)
    <<<策略模式(Strategy Pattern)
    <<<模板方法模式(Template Pattern)
    <<<外观/门面模式(Facade Pattern)
    <<<建造者模式(Builder Pattern)
    <<<适配器模式(Adapter Pattern)
    <<<原型模式(Prototype Pattern)
    <<<工厂相关模式(Factory Pattern)

  • 相关阅读:
    Java核心技术
    浏览器地址栏输入url回车之后发生了些什么
    Java相关面试题总结+答案(十)
    Java相关面试题总结+答案(九)
    Java相关面试题总结+答案(八)
    Java相关面试题总结+答案(七)
    input type=‘file’方法
    禁止用户复制网页内容
    js添加背景水印
    angular双向绑定
  • 原文地址:https://www.cnblogs.com/jarye/p/14057437.html
Copyright © 2011-2022 走看看