一. 核心思想
当一个对象的状态发生改变时,与他相关联的部分对象的状态同时也会发生改变.
例如: ABC同时观察a, a发生变化时, ABC都会收到通知.
二. 简单实现
B1和B2同时观察A. 当A变化时, B1和B2都能收到通知.
public interface IA {
void addObserver(IB ib);
void refresh();
}
public class A implements IA{
private List<IB> mList = new ArrayList<>();
@Override
public void addObserver(IB ib) {
if(!mList.contains(ib)){
mList.add(ib);
}
}
@Override
public void refresh() {
for (int i = 0; i < mList.size(); i++) {
mList.get(i).refreshFinish();
}
}
}
public interface IB {
void refreshFinish();
}
public class B1 implements IB {
@Override
public void refreshFinish() {
Log.d("66", "B1收到refreshFinish");
}
}
public class B2 implements IB {
@Override
public void refreshFinish() {
Log.d("66", "B2收到refreshFinish");
}
}
调用
//被观察者
A a = new A();
//观察者
B1 b1 = new B1();
B2 b2 = new B2();
//注册关联
a.addObserver(b1);
a.addObserver(b2);
//发生变化
a.refresh();
结果:
2019-03-08 18:06:43.214 7329-7329/com.liys.modelobserver D/66: B1收到refreshFinish
2019-03-08 18:06:43.214 7329-7329/com.liys.modelobserver D/66: B2收到refreshFinish
三. 角色划分
观察者(Observer): IB
具体观察者(Concrete Observer): B1, B2
被观察者(Observable): IA
具体被观察者(Concrete Observable): A
四. Java中自带观察者模式
JDK中Observable类和Observer接口实现
- JDK中有Observable类和Observer接口
- 观察者实现Observer接口,被观察者继承Observable类
- 被观察者通过Observable类的addObserver方法添加观察者
/**
* 观察者
*/
public class MyObserver implements Observer {
String name;
public MyObserver(String name){
this.name = name;
}
@Override
public void update(Observable o, Object arg) {
//被观察者改变后, 发起通知, 会调用这个方法
Log.d("66", name + " 消息 = " + arg);
}
}
/**
* 被观察者
*/
public class MyObservable extends Observable {
public void sendChangeMeg(String content) {
//方法继承自Observable,标示状态或是内容发生改变
setChanged();
//方法继承自Observable,通知所有观察者,最后会调用每个Observer的update方法
notifyObservers(content);
}
}
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//被观察者
MyObservable myObservable = new MyObservable();
//观察者
MyObserver myObserver1 = new MyObserver("Observer1");
MyObserver myObserver2 = new MyObserver("Observer2");
//注册关联
myObservable.addObserver(myObserver1);
myObservable.addObserver(myObserver1);
myObservable.addObserver(myObserver2);
myObservable.sendChangeMeg("消息来了");
}
}
打印结果:
Observer2 消息 = 消息来了
Observer1 消息 = 消息来了
为什么打印顺序是反过来的呢? 看源码
addObserver.png从上图我们看到, 观察者加进去的时候是加到Vector集合中的,Vector是list的一个子类, 也就是按顺序添加的. 但是notifyObservers取出来的时候关键代码如下: 是按倒序取出来的, 所以才会有后进先出这个现象,.
public void notifyObservers(Object arg) {
synchronized (this) {
for (int i = arrLocal.length-1; i>=0; i--)
((Observer)arrLocal[i]).update(this, arg);
}
}
网友评论