观察者模式也被称为发布-订阅(Publish/Subscribe)模式,它属于行为型模式的一种。观察者模式定义了一种一对多的依赖关系,一个主题对象可被多个观察者对象同时监听。当这个主题对象状态变化时,会通知所有观察者对象并作出相应处理逻辑。
模型图
![4835249-56d851e24562cb14.jpg](https://img.haomeiwen.com/i11333460/c07524e6269cb343.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)观察者模式定义了四种角色:抽象主题、具体主题、抽象观察者、具体观察者。
抽象主题(Subject):该角色是一个抽象类或接口,定义了增加、删除、通知观察者对象的方法。
具体主题(ConcreteSubject):该角色继承或实现了抽象主题,定义了一个集合存入注册过的具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知。
抽象观察者(Observer):该角色是具体观察者的抽象类,定义了一个更新方法。
具体观察者(ConcrereObserver):该角色是具体的观察者对象,在得到具体主题更改通知时更新自身的状态。
实现代码
抽象观察者(Observer)接口
public interface Observer{
public void update(string msg);
}
具体观察者(ConcreteObserver)类
public class ConcreteObserver implement Observer{
private mName = name;
public ConcreteObserver(String name){
mName = name;
}
public void update(string msg){
Toast.makeToast(this, mName + msg, 0).show();
}
}
抽象主题(Subject)接口
public class Subject{
public void register(Observer observer);
public void unregister(Observer observer);
public void notifyAll(string msg);
}
具体主题(ConcreteSubject)类
public class ConcreteSubject implement Subject{
ArrayList<Observer> observers;
public Subject(){
observers = new ArrayList<Observer>();
}
@Override
public void register(Observer observer){
observers.add(observer);
}
@Override
public void unregister(Observer observer){
observers.remove(observer);
}
@Override
public void notifyAll(string msg){
for (Observer observer : observers ) {
observer.update(msg);
}
public void notifyDataChange(String newMsg){
notifyAll(newMsg);
}
}
MainActivity类
public class MainActivity extends Activity{
public void onCreate(Bundle savedInstanceState){
ConcreteSubject subject = new ConcreteSubject();
subject.register(new ConcreteObserver("test1");
subject.register(new ConcreteObserver("test2");
Button btn = findviewbyId(R.id.test);
btn.setOnclickListener(new OnClickListener{
@Override
public void onClick(View view){
subject.notifyDataChange("我变了,请注意查收");
}
}
}
优点
1.观察者模式符合松耦合
通过一个列表来维护观察者,这使得被观察者无需在意观察者的具体类型,只需要发送消息进行通知即可,通过调用update方法,观察者也无须关系被观察者的情况,只当有状态改变时进行更新即可。观察者增加或删除无需修改主题的代码,只需调用主题对应的增加或者删除的方法即可。
2.观察者不会因主动获取通知而错过状态
由于被动接受,正常情况下不会错过主题的改变通知。而主动获取的话,由于时机选取问题,可能导致错过某些状态。
3.表示层和数据逻辑层的分离
观察者模式可以实现表示层和数据逻辑层的分离,并定义了稳定的消息更新传递机制,抽象了更新接口,使得可以有各种各样不同的表示层作为具体观察者角色。观察者模式在观察目标和观察者之间建立一个抽象的耦合。观察者模式支持广播通信。观察者模式符合“开闭原则”的要求。
缺点
1.如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间
2.虽然观察者模式可以随时使观察者知道所观察的对象发生了变化,但是观察者模式没有相应的机制使观察者知道所观察的对象是怎么发生变化的
应用场景:
1、 对一个对象状态的更新,需要其他对象同步更新,而且其他对象的数量动态可变。
2、 对象仅需要将自己的更新通知给其他对象而不需要知道其他对象的细节。
网友评论