java.util 中Observer与Observable

Observer 观察者

Observer源码分析

package java.util;

@Deprecated(since="9")
public interface Observer {
	//只要改变了 observable 对象就调用此方法。应用程序调用 Observable 对象的 notifyObservers 方法,便向所有该对象的观察者通知此改变。 
	//参数:
	//o - observable 对象。
	//注意! arg是被观察对象notifyObservers方法传入的参数
    void update(Observable o, Object arg);
}

当被观察对象发生改变时,观察者再调用update方法,它得到消息时并不真实知道被观察对象是否已经发生改变,具体原因在Observable中。个人认为观察者模式中被观察对象将要改变和已经该变应该分开同等对对待,有时在对象改变前接收到信息更重要。

Observable 可观察对象

Observable源码分析

package java.util;

@Deprecated(since="9")
public class Observable {
	//是否改变的标志
    private boolean changed = false;
    //观察者集合,利用Vector同步方法来线程安全
    private Vector<Observer> 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);
    }
   //当不传递消息给notifyObservers方法时,仍然通知所有观察者
    public void notifyObservers() {
        notifyObservers(null);
    }
	//通过判断changed决定是否发出通知
    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;
    }
	//观察者数量
    public synchronized int countObservers() {
        return obs.size();
    }
}

Observable是一个具体实现类,由于java的类单继承性,只继承Observable来实现观察者模式。

代码测试

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

public class TestObserable {

	public static void main(String[] args) {
		Teacher teacher=new Teacher();
		Student s1=new Student("Student 1");
		s1.addObserver(teacher);
		s1.addObserver(teacher);
		s1.setName("Student 2");
	}

}
class  Teacher  implements Observer{

	public void update(Observable obs, Object arg) {
		System.out.println(((Student)obs).getName()+ "-->"+arg);
	}
	
}

class Student extends Observable {
    private String name = "";

    public Student(String name) {
		this.name=name;
	}
	public String getName() {
        return name;
    }
    public void setName(String newName) {
        if (!name.equals(newName)){
            name = newName;
            setChanged();    
            notifyObservers(newName);
        }
    }
}

结果:

Student 2–>Student 2

    public void setName(String newName) {
        if (!name.equals(newName)){
            setChanged(); 
            notifyObservers(newName);   
            name = newName;
        }
    }
结果:

Student 1–>Student 2

后续

虽然在jdk9以后已经不建议使用了,但是观察者模式在UI编程中表现优越。在JavaFX得到充分的发展成为javafx.beans的重要接口,并延伸出属性与绑定,可观察对象从单一对象拓展到可观察集合乃至任意类型。
虽然JDK11将javafx移除了,但这也是为了 javafx更长远的发展

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值