观察者模式一般都用inner class来实现,比如Android中如下的类:

public abstract class AbstractCursor {
    public void setNotificationUri(ContentResolver cr, Uri notifyUri) {
            mSelfObserver = new SelfContentObserver(this);
        }
    }

     /**
     * Cursors use this class to track changes others make to their URI.
     */
    protected static class SelfContentObserver extends ContentObserver {
        WeakReference mCursor;

        public SelfContentObserver(AbstractCursor cursor) {
            super(null);
            mCursor = new WeakReference(cursor);
        }

        @Override
        public boolean deliverSelfNotifications() {
            return false;
        }

        @Override
        public void onChange(boolean selfChange) {
            AbstractCursor cursor = mCursor.get();
            if (cursor != null) {
                cursor.onChange(false);
            }
        }
    }
}

这里使用了很少见的WeakReference(弱引用):

weak-ref

因为在一般的Observer模式中,对于observer本身可能因为忘记unregister(或者在异常情况下没有unregister),这会导致内存的泄漏。这里在AbstractCursor和observer之间建立了弱引用,让前者可以及时得到回收。而observer和event source还是强引用,可能因为observer还是很亲量级的原因吧。

比较如下的另外一种实现,这种实现更加普遍:

public abstract class CursorAdapter  {
    protected void init(Context context, Cursor c, boolean autoRequery) {
        mChangeObserver = new ChangeObserver();
    }
    private class ChangeObserver extends ContentObserver {
        public ChangeObserver() {
            super(new Handler());
        }

        @Override
        public boolean deliverSelfNotifications() {
            return true;
        }

        @Override
        public void onChange(boolean selfChange) {
            onContentChanged();
        }
    }

如果你对内部类很熟悉的话(我是一点都不熟,重翻了遍thinking in java,经典啊),就会发现最前面的那种实现其实是nested class,后面一种才是inner class,由于inner class默认存在一个到“父类”的强引用,所以如果要用弱引用的话,必须把它改造成nested class(static class必为nested class),通过构造函数来传递“父类”的引用。

另:我用Rational Team Concert的Find bugs,对没有使用内置强引用的inner class但是没有声明为static的,有这样的建议:

Pattern: Should be a static inner class
id: SIC_INNER_SHOULD_BE_STATIC, type: SIC, category: PERFORMANCE

This class is an inner class, but does not use its embedded reference to the object which created it.  This reference makes the instances of the class larger, and may keep the reference to the creator object alive longer than necessary.  If possible, the class should be made static.

弱引用孙卫琴老师的这篇对象的强、软、弱和虚引用讲的很透彻,虽然没有多高明多复杂的地方,但是简单明了,难得。