• 观察者模式


    定义

    定义对象间的一对多的关系,使得每当一个对象的状态改变,则所有依赖与它的对象都会得到通知并被自动更新

    使用场景

    1. 观察者和被观察者是抽象耦合,利于扩展
    2. 一个对象的改变将会导致一个或多个对象的改变,不清楚具体有多少对象以及这些被影响的对象是谁的情况
    3. 如果有这样一个影响链的情况下也可以使用,例如A的改变会影响B,B的改变会影响C......,可以使用观察者模式设计一个链式触发机制。

    实现方式

    被观察者,商品类

    import java.math.BigDecimal;
    import java.util.Observable;
    
    public class Product extends Observable {
    
        protected String name;
        protected BigDecimal price;
        
        public Product(String name, BigDecimal price) {
    		super();
    		this.name = name;
    		this.price = price;
    	}
       
    	public String getName() {
    		return name;
    	}
    
    	public BigDecimal getPrice() {
    		return price;
    	}
    
    	/**
         * 商品名称变更
         * @param name 商品名称
         */
        public void setName(String name){
            this.name = name;
            setChanged();
            //通知观察者
            notifyObservers(name);
        }
    
        /**
         * 价格变更
         * @param price 商品价格
         */
        public void setPrice(BigDecimal price){
            this.price = price;
            setChanged();
            //通知观察者
            notifyObservers(price);
        }
    }
    

    观察者类,名称观察者

    import java.util.Observable;
    import java.util.Observer;
    
    public class NameObserver implements Observer {
    	
        /**
         * 更新
         */
        @Override
        public void update(Observable observable, Object arg) {
            if(arg instanceof String){
                String name = (String) arg;
                System.out.println("您关注的商品名称发生了变化,最新的商品名称是"+name);
            }
        }
    }
    

    观察者类,价格观察者

    import java.math.BigDecimal;
    import java.util.Observable;
    import java.util.Observer;
    
    public class PriceObserver implements Observer{
    
        /**
         * 更新
         * @param obj 更新对象
         */
        @Override
        public void update(Observable observable, Object arg) {
            if(arg instanceof BigDecimal){
                BigDecimal price = (BigDecimal)arg;
                System.out.println("您关注的商品价格发生了变化,最新的商品价格是:"+price);
            }
        }
    }
    

    客户端调用

    import java.math.BigDecimal;
    
    public class Test {
    
        public static void main(String[] args) {
    
            Product product = new Product("iphone 6",new BigDecimal(8999));
            System.out.println("您关注的商品的名称是:"+product.getName()+",价格是:"+product.getPrice());
            //创建观察者
            NameObserver nameObserver = new NameObserver();
            PriceObserver priceObserver = new PriceObserver();
            //加入观察者
            product.addObserver(nameObserver);
            product.addObserver(priceObserver);
            //产生变化,通知观察者
            product.setName("iphone 7");
            product.setPrice(new BigDecimal(12999));
        }
    }  
    

    扩展与思考

    1. 观察者模式与之前学习的Javascript回调函数类似,JQuery中有jQuery.Callbacks(flags),都有一套触发机制
    2. JDK中提供了java.util.Observable实现类和java.util.Observer的接口,所以实际中我们可以直接使用,而不用自己去写重复代码和建立对应的接口。
    3. 异步处理问题,一般观察者的模式默认是顺序执行的,一旦中间观察者卡壳,会影响整体的执行效率,需要考虑异步。
    4. 广播链问题,比如数据库的触发器,表A的触发器,修改表B字段,表B的触发器触发修改表C...也就是一个观察者可以有双重身份,即是观察者也是被观察者。
    5. 观察者模式可以考虑使用RxJava框架,来解决3和4的问题,还对接口柯西化处理,运用链式编程风格,使用方便。
  • 相关阅读:
    人脉是麻烦出来的
    oracle撤销表空间和回滚段
    linux虚拟机ip地址更改
    linux各个文件夹的用途
    Apache的配置文件http.conf参数含义详解
    账户管理_新建用户_用户组
    【刷题】BZOJ 3994 [SDOI2015]约数个数和
    【刷题】BZOJ 2301 [HAOI2011]Problem b
    【刷题】洛谷 P3455 [POI2007]ZAP-Queries
    【刷题】BZOJ 2820 YY的GCD
  • 原文地址:https://www.cnblogs.com/fzsyw/p/11326108.html
Copyright © 2020-2023  润新知