观察者模式之----Observable和Observer是怎么实现奇妙的通知功能的

本文深入解析观察者模式的核心概念,通过具体示例代码,详细讲解了如何在Java中实现观察者模式,并深入分析了Java的Observable类源码。包括核心组件、状态变化触发机制以及回调方法的应用,旨在帮助开发者理解和掌握这一经典设计模式。

     不说,先给出示例代码。首先,说明一下,我这个例子里面的观察者观察了两个事件(被观察者)

报纸观察员和电视观察员。

1、报纸观察员(当publish方法被调用,观察员负责通知所有观察了他的人,告诉他们有新报纸)

package com.gzmu.observer.observable;

import java.util.Observable;


public class Publisher extends Observable {
    
    private String magazineName;
    


    public String getMagazineName() {
        return magazineName;
    }
    
    public void publish(String magazineName) {
        this.magazineName = magazineName;
        setChanged();
        notifyObservers(this);
    }
    
}


2、电视观察员当(play方法被调用,观察员负责通知所有观察了他的人,告诉他们有新电视)

package com.gzmu.observer.observable;

import java.util.Observable;

public class TVStation extends Observable {


    private String programmeName;

    public void play(String programmeName) {
        this.programmeName = programmeName;
        setChanged();
        notifyObservers(this);
    }

    public String getProgrammeName() {
        return programmeName;
    }
}


3、用户(观察者)

package com.gzmu.observer.observer;

import java.util.Observable;
import java.util.Observer;


import com.gzmu.observer.observable.Publisher;
import com.gzmu.observer.observable.TVStation;

public class Reader implements Observer {

    @Override
    public void update(Observable o, Object arg) {
        if (o instanceof Publisher) {
            Publisher p = (Publisher) o;
            System.out.println("我要订阅" + p.getMagazineName());
        }
        if (o instanceof TVStation) {
            TVStation t = (TVStation) o;
            System.out.println("我要收看" + t.getProgrammeName());
        }
    }

}


4、测试代码

package com.gzmu.observer.test;

import org.junit.Test;


import com.gzmu.observer.observable.Publisher;
import com.gzmu.observer.observable.TVStation;
import com.gzmu.observer.observer.Reader;


public class TestCase {
    
    @Test
    public void register() {
        
        Reader reader = new Reader();
        
        Publisher publisher = new Publisher();
        publisher.addObserver(reader);
        
        TVStation tvStation = new TVStation();
        tvStation.addObserver(reader);
        
        publisher.publish("Kent.Kwan的技术空间");
        
        tvStation.play("色戒");
        
    }
    
}


       说说我对观察者模式的理解。从事例开始说。我觉得最核心的就是Observable这个类。

Observable里面有一个Observer类型的数组,数组里面每个元素就是我们添加的参与

观察的对象,比如Person(实现Observer接口)。只要Observable调用了setChanged, 状态

位就会被置为true,这时候,再调用notifyObservers()就会遍历数组,然后逐个对每个observer

对象调用update方法(代码见下面),于是我们自己写的update方法(如Person里的update)

就会被调用,这里面用到了回调的方法。


分析java源代码:

 
package java.util;

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;
   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;
    }

 
    public synchronized int countObservers() {
return obs.size();
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值