1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > java observer update_Java_观察者模式(Observable和Observer)

java observer update_Java_观察者模式(Observable和Observer)

时间:2023-01-17 08:52:47

相关推荐

java observer update_Java_观察者模式(Observable和Observer)

java.util.Observable中有两个方法对Observer特别重要

①setChanged()方法

/**

*Setsthechangedflagforthis{@codeObservable}.Aftercalling

*{@codesetChanged()},{@codehasChanged()}willreturn{@codetrue}.

*/

protectedvoidsetChanged(){

changed=true;

}

②notifyObservers()方法 / notifyObservers(Object data)方法

/**

*If{@codehasChanged()}returns{@codetrue},callsthe{@codeupdate()}

*methodforeveryobserverinthelistofobserversusingnullasthe

*argument.Afterwards,calls{@codeclearChanged()}.

*

*Equivalenttocalling{@codenotifyObservers(null)}.

*/

publicvoidnotifyObservers(){

notifyObservers(null);

}

/**

*If{@codehasChanged()}returns{@codetrue},callsthe{@codeupdate()}

*methodforeveryObserverinthelistofobserversusingthespecified

*argument.Afterwardscalls{@codeclearChanged()}.

*

*@paramdata

*theargumentpassedto{@codeupdate()}.

*/

@SuppressWarnings("unchecked")

publicvoidnotifyObservers(Objectdata){

intsize=0;

Observer[]arrays=null;

synchronized(this){

if(hasChanged()){

clearChanged();

size=observers.size();

arrays=newObserver[size];

observers.toArray(arrays);

}

}

if(arrays!=null){

for(Observerobserver:arrays){

observer.update(this,data);

}

}

}

以上两个方法十分重要

setChanged()方法 ——

用来设置一个内部标志位注明数据发生了变化

notifyObservers()方法 / notifyObservers(Object data)方法 ——

通知所有的Observer数据发生了变化,这时所有的Observer会自动调用复写好的update(Observable observable, Object data)方法来做一些处理(比如说画面数据的更新)。

我们可以看到通知Observer有两个方法,一个无参,一个有参。那么这个参数有什么作用呢?

其中一个作用:现在我不想通知所有的Observer,而只想其中一个指定的Observer做一些处理,那么就可以传一个参数作为ID,然后在所有的Observer中判断,每个Observer判断只有接收到底参数ID是属于自己的才做一些处理。

当然参数还有其他作用,我只是举了个例子。

下面举个例子加以说明:

importjava.util.Observable;

/**

*被观察者类

*/

publicclassSimpleObservableextendsObservable

{

privateintdata=0;

publicintgetData(){

returndata;

}

publicvoidsetData(inti){

if(this.data!=i){

this.data=i;

setChanged();

//只有在setChange()被调用后,notifyObservers()才会去调用update(),否则什么都不干。

notifyObservers();

}

}

}

上面这个类是一个被观察者类,它继承了Observable类,表示这个类是可以被观察的。

然后在setData()方法里面,也就是数据改变的地方,来调用Observable类的setChanged()方法和notifyObservers()方法,表示数据已改变并通知所有的Observer调用它们的update()方法做一些处理。

注意:只有在setChange()被调用后,notifyObservers()才会去调用update(),否则什么都不干。

/**

*观察者类

*/

publicclassSimpleObserverimplementsObserver

{

publicSimpleObserver(SimpleObservablesimpleObservable){

simpleObservable.addObserver(this);

}

publicvoidupdate(Observableobservable,Objectdata){//data为任意对象,用于传递参数

System.out.println(“Datahaschangedto”+(SimpleObservable)observable.getData());

}

}

通过生成被观察者(SimpleObservable类)的实例,来调用addObserver(this)方法让观察者(SimpleObserver类)达到观察被观察者(SimpleObservable类)的目的。

然后还要复写update()方法,做数据改变后的一些处理。

下面可以写一个简单的测试类来测试一下

publicclassSimpleTest

{

publicstaticvoidmain(String[]args){

SimpleObservabledoc=newSimpleObservable();

SimpleObserverview=newSimpleObserver(doc);

doc.setData(1);

doc.setData(2);

doc.setData(2);

doc.setData(3);

}

}

运行结果如下

Datahaschangedto1

Datahaschangedto2//第二次setData(2)时由于没有setChange,所以update没被调用

Datahaschangedto3

下面介绍一个Observable类的其他一些属性和方法

属性 ——

//observers是一个List,保存着所有要通知的observer。

Listobservers=newArrayList();

//changed是一个boolean型标志位,标志着数据是否改变了。

booleanchanged=false;

方法 ——

//添加一个Observer到列表observers中

publicvoidaddObserver(Observerobserver){

if(observer==null){

thrownewNullPointerException();

}

synchronized(this){

if(!observers.contains(observer))

observers.add(observer);

}

}

//从列表observers中删除一个observer

publicsynchronizedvoiddeleteObserver(Observerobserver){

observers.remove(observer);

}

//清空列表observers

publicsynchronizedvoiddeleteObservers(){

observers.clear();

}

//返回列表observers中observer的个数

publicintcountObservers(){

returnobservers.size();

}

//重置数据改变标志位为未改变

protectedvoidclearChanged(){

changed=false;

}

//将数据改变标志位设置为改变

protectedvoidsetChanged(){

changed=true;

}

//判断标志位的值

publicbooleanhasChanged(){

returnchanged;

}

//通知所有observer(无参)

publicvoidnotifyObservers(){

notifyObservers(null);

}

//通知所有observer(有参)

@SuppressWarnings("unchecked")

publicvoidnotifyObservers(Objectdata){

intsize=0;

Observer[]arrays=null;

synchronized(this){

if(hasChanged()){

clearChanged();

size=observers.size();

arrays=newObserver[size];

observers.toArray(arrays);

}

}

if(arrays!=null){

for(Observerobserver:arrays){

observer.update(this,data);

}

}

}

注意:在Observer对象销毁前一定要用deleteObserver将其从列表中删除,也就是在onDestroy()方法中调用deleteObserver()方法。

不然因为还存在对象引用的关系,Observer对象不会被垃圾收集,造成内存泄漏,并且已死的Observer仍会被通知到,有可能造成意料外的错误,而且随着列表越来越大,notifyObservers操作也会越来越慢。

下面2个工程是Observable与Observer的经典运用,是android实现的单指拖动放大图片的操作

两个例子:

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。