观察者模式--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来发送异步的消息在主线程上来执行相应的操作。

时间: 2024-10-08 15:13:36

观察者模式--Java设计模式的相关文章

Java设计模式(八) 适配器模式

原创文章,转载请务必将下面这段话置于文章开头处. 本文转发自Jason's Blog,原文链接 http://www.jasongj.com/design_pattern/adapter/ 适配器模式介绍 适配器模式定义 适配器模式(Adapter Pattern),将一个类的接口转换成客户希望的另外一个接口.适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. 适配器模式类图 适配器模式类图如下 适配器模式角色划分 目标接口,如上图中的ITarget 具体目标实现,如Concr

设计模式之第18章-观察者模式(Java实现)

设计模式之第18章-观察者模式(Java实现) 话说曾小贤,也就是陈赫这些天有些火,那么这些明星最怕的,同样最喜欢的是什么呢?没错,就是狗仔队.英文的名字比较有意思,是paparazzo,这一说法据说来自意大利电影<滴露牡丹开>中一个专门偷拍明星照片的一个摄影师的名字,“Paparazzo”,中文译为帕帕拉齐,俗语就是狗仔队.这些明星因狗仔队而荣,获得曝光率,也因狗仔队而损,被曝光负面新闻,不管怎么说,总之是“火起来了”,让明星们又爱又恨.(众人:鱼哥,你扯远了).咳咳,这个狗仔队其实嘛,也就

理解java设计模式之观察者模式

在生活实际中,我们经常会遇到关注一个事物数据变化的情况,例如生活中的温度记录仪,当温度变化时,我们观察它温度变化的曲线,温度记录日志等.对于这一类问题,很接近java设计模式里面的“观察者模式”,它适合解决多种对象跟踪一个对象数据变化的程序结构问题. 观察者设计模式涉及到两种角色:主题(Subject)和观察者(Observer) 下面以java JDK中已有的观察者设计模式代码,展示使用: 1.主题(Subject):Observable类派生出来的子类,只需要定义各被监控的数据及getter

java设计模式--观察者模式和事件监听器模式

文章转载于:http://www.java2000.net/p9452 复习设计模式,看到observer观察者模式,说法是该模式和iterator迭代器模式类似已经被整合进jdk,但是jdk提供了两种接口: 一.java.util.Observer -- 观察者接口 对应: java.util.Observable --受查者根类 二.java.util.EventListener -- 事件监听/处理接口 对应: java.util.EventObject -- 事件(状态)对象根类 研究了

大话设计模式_观察者模式(Java代码)

观察者模式:定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态发生变化时,会通知所有观察者对象,使他们自己能够自动更新自己.简单描述:1个Subject类(可以是抽象类可以是接口),可以有多个具体Subject类(继承抽象Subject),此具体Subject持有多个观察者的引用,在此具体Subject状态发生变化的时候调用这些观察者的相应方法.另外,这些持有的引用是抽象的,不是具体的,而这些引用所指向的对象时具体的观察者(即需要作出更新的具体观察者,这些具体

Java设计模式之观察者模式(Observer Pattern)

Observer Pattern 是一种常用的设计模式,它是一种事件监听模型.该模式有两个角色,一个是Subject, 另一个是Observer.Subject 保存有多个Observer的引用,一旦特定的事件发生,Subject会通知它所有的Observer,Observer得到该通知后执行相关程序逻辑.其中,Observer只有先向Subject注册后才能被Subject知晓.这就像订报纸,只有我们向出版社提出订报的申请,出版社才会把我们列入订阅者名单,然后每当新报纸印好时,出版社会通知订阅

Java设计模式(八)观察者模式 迭代器模式

(十五)观察者模式 观察者模式,定义对象间一对多关系,一个对象状态发生改变,所有依赖于它的对象都收到通知并且自动更新,观察者与被观察者分开.例如邮件订阅.RSS订阅,如果有更新就会邮件通知你. interface Observers{ public void update(); } class Observer1 implements Observers{ public void update(){ System.out.println("observer1 has received"

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

[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/3899208.html 联系方式:[email protected] [正文] 一.观察者模式的定义: 简单地说,观察者模式定义了一个一对多的依赖关系,让一个或多个观察者对象监听一个主题对象.这样一来,当被观察者状态发生改变时,需要通知相应的观察者,使这些观察者对象能够自动更新.例如:GUI中的事件

Java 设计模式系列(十六)观察者模式(Observer)

Java 设计模式系列(十六)观察者模式(Observer) 观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式.模型-视图(Model/View)模式.源-监听器(Source/Listener)模式或从属者(Dependents)模式. 观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己. 一.观察者模式的结构 Subject:目标对象,通常具有如下功能: