Java内置Observerable类的源码分析

package java.util;
/** * This class represents an observable object, or "data" 
	* in the model-view paradigm. It can be subclassed to represent an 	
	* object that the 	application wants to have observed. 
	* 

* An observable object can have one or more observers. An observer * may be any object that implements interface Observer. After an * observable instance changes, an application calling the * Observable's notifyObservers method * causes all of its observers to be notified of the change by a call * to their update method. *

* The order in which notifications will be delivered is unspecified. * The default implementation provided in the Observable class will * notify Observers in the order in which they registered interest, but * subclasses may change this order, use no guaranteed order, deliver * notifications on separate threads, or may guarantee that their * subclass follows this order, as they choose. *

* Note that this notification mechanism has nothing to do with threads * and is completely separate from the wait and notify * mechanism of class Object. *

* When an observable object is newly created, its set of observers is * empty. Two observers are considered the same if and only if the * equals method returns true for them. * * @author Chris Warth * @see java.util.Observable#notifyObservers() * @see java.util.Observable#notifyObservers(java.lang.Object) * @see java.util.Observer * @see java.util.Observer#update(java.util.Observable, java.lang.Object) * @since JDK1.0 */public class Observable { private boolean changed = false; private Vector obs; /** Construct an Observable with zero Observers. */ public Observable() { obs = new Vector<>(); } /** * Adds an observer to the set of observers for this object, provided * that it is not the same as some observer already in the set. * The order in which notifications will be delivered to multiple * observers is not specified. See the class comment. * * @param o an observer to be added. * @throws NullPointerException if the parameter o is null. */ public synchronized void addObserver(Observer o) { if (o == null) throw new NullPointerException(); if (!obs.contains(o)) { obs.addElement(o); } } /** * Deletes an observer from the set of observers of this object. * Passing null to this method will have no effect. * @param o the observer to be deleted. */ public synchronized void deleteObserver(Observer o) { obs.removeElement(o); } /** * If this object has changed, as indicated by the * hasChanged method, then notify all of its observers * and then call the clearChanged method to * indicate that this object has no longer changed. *

* Each observer has its update method called with two * arguments: this observable object and null. In other * words, this method is equivalent to: *

* notifyObservers(null)
* * @see java.util.Observable#clearChanged() * @see java.util.Observable#hasChanged() * @see java.util.Observer#update(java.util.Observable, java.lang.Object) */ public void notifyObservers() { notifyObservers(null); } /** * If this object has changed, as indicated by the * hasChanged method, then notify all of its observers * and then call the clearChanged method to indicate * that this object has no longer changed. *

* Each observer has its update method called with two * arguments: this observable object and the arg argument. * * @param arg any object. * @see java.util.Observable#clearChanged() * @see java.util.Observable#hasChanged() * @see java.util.Observer#update(java.util.Observable, java.lang.Object) */ public void notifyObservers(Object arg) { /* * a temporary array buffer, used as a snapshot of the state of * current Observers. */ Object[] arrLocal; synchronized (this) { /* We don't want the Observer doing callbacks into * arbitrary code while holding its own Monitor. * The code where we extract each Observable from * the Vector and store the state of the Observer * needs synchronization, but notifying observers * does not (should not). The worst result of any * potential race-condition here is that: * 1) a newly-added Observer will miss a * notification in progress * 2) a recently unregistered Observer will be * wrongly notified when it doesn't care */ if (!changed) return; arrLocal = obs.toArray(); clearChanged(); } for (int i = arrLocal.length-1; i>=0; i--){ ((Observer)arrLocal[i]).update(this, arg); } /** * Clears the observer list so that this object no longer has any * observers. */ public synchronized void deleteObservers() { obs.removeAllElements(); } /** * Marks this Observable object as having been changed; the * hasChanged method will now return true. */ protected synchronized void setChanged() { changed = true; } /** * Indicates that this object has no longer changed, or that it has * already notified all of its observers of its most recent change, * so that the hasChanged method will now return false. * This method is called automatically by the * notifyObservers methods. * * @see java.util.Observable#notifyObservers() * @see java.util.Observable#notifyObservers(java.lang.Object) */ protected synchronized void clearChanged() { changed = false; } /** * Tests if this object has changed. * * @return true if and only if the setChanged * method has been called more recently than the * clearChanged method on this object; * false otherwise. * @see java.util.Observable#clearChanged() * @see java.util.Observable#setChanged() */ public synchronized boolean hasChanged() { return changed; } /** * Returns the number of observers of this Observable object. * * @return the number of observers of this object. */ public synchronized int countObservers() { return obs.size(); } }

源码简析:

  1. 此类中使用vector集合,这个集合应该是被废弃的,因为这个集合是一个多线程安全的集合,为了线程安全,使用了时间换空间的策略,所以时间很慢,再加上对元素的增删速度慢,成为弃婴。

  2. vector的优点:

    • 线程同步

    • 数组是数组长度可变(当数组动态扩容需要消耗不少时间,影响性能)

    • 特有的方法:

      ​ void addElement(E obj) 在集合末尾添加元素

      ​ E elementAt( int index) 返回指定角标的元素

      ​ Enumeration elements() 返回集合中的所有元素,封装到Enumeration对象中测试此枚举是否包含更多的元素。

      ​ E nextElement() 如果此枚举对象至少还有一个可提供的元素,则返回此枚举的下一个元素。

      ​ Enumeration 接口: boolean hasMoreElements()

  3. 此类中添加了一个changed的布尔标识,用来发现被观察者的信息是否变化

  4. 在注册/移除观察者时,添加了synchronized锁,防止其他线程执行里面的代码造成数据不安全

  5. 改变类变量的方法好像他都锁了一下

  6. 在执行notifyObserver(object o)方法时,判断了一下changed,false就直接返回,不做更新操作;true的话就将changed重置为false,然后将更新的信息发给每一个观察者

java内置的Observerable的缺点

  1. 它使用的是类定义而不是接口定义,这样会使得这个类减少复用机会,而且不容易扩展

  2. 它违背了“设计应该多使用组合,少使用继承”的设计原则,比如在方法中添加了protest关键字,使得只用继承此类的类才能使用此方法。

    除了util包外,在swings包和javabeans包也体现了observer模式。其实mvc模式也是观察者模式的代表。

​ em...... 大致就这些东西.

你可能感兴趣的:(Java内置Observerable类的源码分析)