• 观察者模式


    观察者模式是对象的行为模式,又叫发布-订阅模式,模型-视图模式,源-监听器模式或者从属者模式。观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己。(解释引用于-java与模式)

    客户端

    package Observer;
    /*
     * @auther 顶风少年
     * @mail dfsn19970313@foxmail.com
     * @date 2019-12-17 14:56
     * @notify 模拟客户端
     * @version 1.0
     */
    
    public class Client {
        //如果在spring项目中,我们可以把subject注册到容器中。当前做法仅想表示初始化一次。
        static OrderSubject subject = null;
    
        static {
            subject = new OrderSubject();
            subject.attach(new ChangeAccount());
            subject.attach(new ChangeInventory());
        }
    
    
        public static void main(String[] args) {
            //用户购买商品,付款成功
            Order order = new Order("张三", "苹果");
            //调用所有监听者,执行各自操作
            subject.notifyObservers(order);
        }
    }
    View Code

    业务pojo

    package Observer;
    
    /*
     * @auther 顶风少年
     * @mail dfsn19970313@foxmail.com
     * @date 2019-12-17 14:45
     * @notify  用于模拟订单信息
     * @version 1.0
     */
    public class Order {
    
        public Order(String userId, String goodsId) {
            this.userId = userId;
            this.goodsId = goodsId;
        }
    
        //用户id
        private String userId;
        //商品id
        private String goodsId;
    
        public String getUserId() {
            return userId;
        }
    
        public void setUserId(String userId) {
            this.userId = userId;
        }
    
        public String getGoodsId() {
            return goodsId;
        }
    
        public void setGoodsId(String goodsId) {
            this.goodsId = goodsId;
        }
    }
    View Code

    订阅主题

    package Observer;
    import java.util.ArrayList;
    import java.util.List;
    /*
     * @auther 顶风少年
     * @mail dfsn19970313@foxmail.com
     * @date 2019-12-17 10:49
     * @notify 订单主题
     * @version 1.0
     */
    
    public class OrderSubject {
    
        private List<Observer> observersList = new ArrayList<>();
    
        //调用这个方法登记一个新的观察者对象
        public void attach(Observer observer) {
            observersList.add(observer);
        }
    
        //调用这个方法删除一个已经登记过的观察者对象
        public void detach(Observer observer) {
            observersList.remove(observer);
        }
    
    
        //调用这个方法通知所有登记过的观察者对象
        public void notifyObservers(Order order) {
            for (Observer observer : observersList) {
                observer.excuse(order);
            }
        }
    }
    View Code

    观察者接口

    package Observer;
    
    /*
    * @auther 顶风少年 
    * @mail dfsn19970313@foxmail.com
    * @date 2019-12-17 10:56
    * @notify  观察者接口
    * @version 1.0
    */
    public interface Observer {
        //执行具体的业务
        void excuse(Order order);
    }
    View Code

    账户余额业务观察者实现

    package Observer;
    
    /*
     * @auther 顶风少年
     * @mail dfsn19970313@foxmail.com
     * @date 2019-12-17 14:51
     * @notify 修改账户余额
     * @version 1.0
     */
    public class ChangeAccount implements Observer {
        //执行具体的业务
        public void excuse(Order order) {
            String userId = order.getUserId();
            System.out.println("正在修改用户:" + userId + "的账户余额");
            System.out.println("账户余额修改成功");
        }
    }
    View Code

    商品库存业务观察者实现

    package Observer;
    
    /*
     * @auther 顶风少年
     * @mail dfsn19970313@foxmail.com
     * @date 2019-12-17 14:51
     * @notify 修改库存
     * @version 1.0
     */
    public class ChangeInventory implements Observer {
        //执行具体的业务
        public void excuse(Order order) {
            String goodsId = order.getGoodsId();
            System.out.println("正在修改商品:" + goodsId + "的库存数量");
            System.out.println("库存数量修改成功");
        }
    }
    View Code

    平时写crud时,会经常遇到上边的业务情况。当一个对象改变,往往需要修改与之相关联的其他几个对象,这里不如说修改其他表更为准确。上边例子,常规来讲我们在用户付款成功后,依次调用扣款接口,库存接口来进行相应的操作。这其实增强了,支付业务和扣款业务,库存业务的耦合性。使用观察者模式,支付业务无需知道用户付款成功后,需要做什么操作,只需要找到主题,然后将消息发布出去即可。其次,我们可以将不同的业务放到不同的订阅组中,观察者和观察者之间没有关联,订阅组和订阅组之间也没有关联。

    观察者模式的缺点也很明显,当一个活动对象有多个观察者,多个观察者循环执行,如果一个观察者出错,就可能造成整个生态的崩溃。

  • 相关阅读:
    linux LVM详解
    Mysql SQL优化系列之——执行计划连接方式浅释
    Vue SSR常见问题、异常处理以及优化方案
    vue组件生命周期详解
    axios全局设置url公共请求头
    WebView中JS调用Android Method 遇到的坑整理
    node.js项目多环境配置
    用vue构建多页面应用
    前端系列-移动端开发踩过的一些坑
    Async:简洁优雅的异步之道
  • 原文地址:https://www.cnblogs.com/zumengjie/p/12054663.html
Copyright © 2020-2023  润新知