观察者模式--Java设计模式

观察者模式定义:定义了对象之间的一对多的依赖,这样一来,当一个对象发生改变状态的时候,它的所有依赖者都会收到通知并自动更新。参考如下图:
观察者模式表达图

观察者设计模式也叫发布-订阅模式。
也可以称作:出版者+订阅者 = 观察者模式
在Android中观察者模式的实例有:广播机制,ContentObserver的注册方式,一个是同步的观察者模式,一个是异步的观察者模式。

当两个对象之间松耦合,它们依然可以交互,但是不清楚彼此的细节,观察者提供了一种对象的设计,可以降低之间的耦合,避免对象的双向依赖。
举例:在Android中很多的Listener是观察者模式,比如点击事件的OnClickListener,就是为了避免对象的双向依赖。

—-先来看看Java源码中的观察者模式:

Observer观察者接口:

package com.daming.java.observer;

public interface Observer {

    void update(Observable observable, Object arg);
}

对象Observable 类的实现

package com.daming.java.observer;

import java.util.Vector;

public class Observable {

    private boolean changed = false;
    private Vector obs;

    public Observable() {
        obs = new Vector();
    }

    public synchronized void addObserver(Observer o) {
        if (o == null)
            throw new NullPointerException();
        if (!obs.contains(o)) {
            obs.addElement(o);
        }
    }

    public synchronized void deleteObserver(Observer o) {
        obs.removeElement(o);
    }

    public void notifyObservers() {
        notifyObservers(null);
    }

    public void notifyObservers(Object arg) {
        Object[] arrLocal;

        synchronized (this) {
            if (!changed)
                return;
            arrLocal = obs.toArray();
            clearChanged();
        }

        for (int i = arrLocal.length - 1; i >= 0; i--)
            ((Observer) arrLocal[i]).update(this, arg);
    }

    public synchronized void deleteObservers() {
        obs.removeAllElements();
    }

    protected synchronized void setChanged() {
        changed = true;
    }

    protected synchronized void clearChanged() {
        changed = false;
    }

    public synchronized boolean hasChanged() {
        return changed;
    }

    /**
     * Returns the number of observers of this <tt>Observable</tt> object.
     * 
     * @return the number of observers of this object.
     */
    public synchronized int countObservers() {
        return obs.size();
    }

}

MyObserver 观察者对象的实现

package com.daming.java.observer;

public class MyObserver implements Observer{

    @Override
    public void update(Observable observable, Object arg) {
        System.out.println("observable :" + observable + "arg :" + arg);
    }
}

MyObserver2 观察者对象的实现

package com.daming.java.observer;

public class MyObserver2 implements Observer{

    @Override
    public void update(Observable observable, Object arg) {
        System.out.println("observable2 :" + observable + "arg2 :" + arg);
    }
}

TestObserver类的实现

package com.daming.java.observer;

public class TestObserver {

    /**
     * @param args
     */
    public static void main(String[] args) {
        Observable observable = new Observable();
        MyObserver myObserver = new MyObserver();
        MyObserver2 myObserver2 = new MyObserver2();
        observable.addObserver(myObserver);
        observable.addObserver(myObserver2);

        observable.setChanged();
        observable.notifyObservers(14);

        observable.setChanged();
        observable.notifyObservers("I am daming");
    }
}

Log输入结果:

observable2 :com.daming.java.observer.Observable@14318bbarg2 :14
observable :com.daming.java.observer.Observable@14318bbarg :14
observable2 :com.daming.java.observer.Observable@14318bbarg2 :I am daming
observable :com.daming.java.observer.Observable@14318bbarg :I am daming

Java源码中上述代码中用的是推模式,当然源码中也有拉模式,即主动查询的模式。拉模式就像广播一样,通过onReceive()方法拉起来一些动作的,还有像ContentObserver可以通过拉模式,当数据库发生改变的时候,通过onChange()方法来调用一些操作。

—-接着我们来看看Android中异步的观察者模式。

ContentObserver就是异步的观察者模式,异步的观察者有什么好处呢?不阻塞观察者的回调。在同步通知中会有阻塞问题,各个Observer的响应方法是串行的,如果有一个observer耗时的话就会阻塞其他observer接收者了,这样就有可能就会引起bug来,所以在设计的时候多考虑一些,是否考虑用异步的观察者模式,让并发处理快一些;我们通过一个简单的demo来学习下异步的观察者模式:

先来看看Observer,这个Android中是抽象的类

package cn.daming.observer.design;

import android.os.Handler;
import android.util.Log;

public abstract class Observer {

    private Handler mHandler;

    public Observer(Handler handler) {
        mHandler = handler;
    }

    public void onChange() {
    }

    public final void dispatchChange() {
        Log.v("daming", "Observer dispatchChange is mHandler== null :" + (mHandler == null));
        if (mHandler == null) {
            onChange();
        } else {
            mHandler.post(new NotificationRunnable());
        }
    }

    private final class NotificationRunnable implements Runnable {

        @Override
        public void run() {
            Log.v("daming", "NotificationRunnable dispatchChange is run ... ");
            Observer.this.onChange();
        }
    }
}

接着来看看ObserverService这个类的实现:

package cn.daming.observer.design;

import java.util.ArrayList;
import java.util.List;

import android.util.Log;

public class ObserverService {

    private int mState;

    private List<Observer> mObservers = new ArrayList<Observer>();

    public final void registerObserver(Observer observer) {
        if (!mObservers.contains(observer)) {
            mObservers.add(observer);
        }
    }

    public final void unregisterObserver(Observer observer) {
        Log.v("daming", "ObserverService unregisterObserver :");
        mObservers.remove(observer);
    }

    public void notifyChange() {
        for (Observer observer : mObservers) {
            observer.dispatchChange();
        }
    }

    public int getState() {
        return mState;
    }

    public void setState(int state) {
        mState = state;
        notifyChange();
    }
}

最后我们来写测试类FirstActivity :

package cn.daming.observer.design;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

import com.daming.designtraning.R;

public class FirstActivity extends Activity {

    private ObserverService mObserverService;
    private Button mButton;
    private int mState = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mButton = (Button) findViewById(R.id.button);

        mObserverService = new ObserverService();
        mObserverService.registerObserver(mFirstObserver);
        mObserverService.setState(++mState);


        mButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                mObserverService.setState(++mState);
            }
        });

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mObserverService.unregisterObserver(mFirstObserver);

    }

    @Override
    protected void onResume() {
        super.onResume();
    }

    @Override
    protected void onStop() {
        super.onStop();
    }

    private Observer mFirstObserver = new Observer(new Handler()) {

        @Override
        public void onChange() {
            int state = mObserverService.getState();
            Log.v("daming", "FirstObserver onChange is run state :" + state);
        }

    };
}

总结:通过Handler来实现异步的观察者模式,即构造Observer对象的时候传一个Handler的对象,这样在回调的时候,就用handler来发送异步的消息在主线程上来执行相应的操作。

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值