java设计模式--观察者模式 Observer

观察者模式定义了一个一对多的依赖关系,让一个或多个观察者对象监察一个主题对象,主题对象在状态上的变化能够通知所有的依赖于此对象的那些观察者对象。


JDK 提供了Observer 接口 和 Observable类:

Observer 接口:只定义了一个方法,update()。当被观察者对象的状态发生变化时,这个方法就会被调用。

Observable类:被观察者类都是java.util.Observable类的子类。

示例:如果一个商品的名称、价格发生变化,要做相应的处理。

    /**
     * 产品,继承Observable,表示是可以被观察的
     */
    public class Product extends Observable {
        private String name;
        private double price;
        public double getPrice() {
            return price;
        }
        public void setPrice(double price) {
            this.price = price;
            //通知观察者
            setChanged();
            notifyObservers(price);
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
            //通知观察者
            setChanged();
            notifyObservers(name);
        }
    }
定义观察者
/**
     * 名称观察者
     */
    public class NameObserver implements Observer {
        public void update(Observable o, Object arg) {
            System.out.println("name observer,name changed"+arg);
        }
    }
    /**
     * 价格观察者
     */
    public class PriceObserver  implements Observer{
        public void update(Observable o, Object arg) {
            System.out.println("price observer ,price changed"+arg);
        }
    }
测试代码:
    public class Test {
        public static void main(String[] args) {
            Product product = new Product();
            NameObserver nameObserver = new NameObserver();
            PriceObserver priceObserver = new PriceObserver();

            //Observable 内部使用Vector 存放Observer,
            //在被观察的对象调用notifyObservers 中,循环Vector调用 对象的update 方法。
            product.addObserver(priceObserver);
            product.addObserver(nameObserver);

            product.setPrice(0.11);
        }
    }

测试后会发现,两个观察者都被调用了。通过JDK 源码会发现只是循环Vector调用 对象的update 方法,并没有做其它的处理。可以重写Observerable类的子类实现自己想要的,子类并可以在单独的线程里通知观察者对象;或者在一个公用的线程里按照次序执行。 


优点:
1)观察者模式在被观察者和观察者之间建立一个抽象的耦合。被观察者角色所知道的只是一个具体观察者列表,每一个具体观察者都符合一个抽象观察者的接口。
2)被观察者会向所有的登记过的观察者发出通知。
缺点:
1)通知一个对象所有的观察者,可能会共费比较长的时间。如:观察者多,一个观察者处理的速度慢。
2)被观察者之间有循环依赖的话,会出现循环调用。
3)观察者模式没有相应的机制使观察者知道所观察的对象是怎么发生变化的。如上例中,价格变化了,会导致“NameObserver” 被调用。




你可能感兴趣的:(java设计模式)