定义
观察者模式也叫订阅-发布者模式,是一种一对一或者一对多的依赖关系,当一个对象改变状态,依赖它的对象会收到通知并自动更新。
观察者模式的结构
观察者模式主要由四个主要部分构成
(1)主题(Subject):主题也叫抽象被观察者,是一个接口,该接口规定了具体主题需要实现的方法,比如,添加、删除观察者以及通知观察者更新数据的抽象方法。
(2)观察者(Observer):观察者是一个接口,该接口规定了具体观察者用来更新数据的方法。
(3)具体主题(ConcreteSubject):具体主题也叫具体被观察者,是实现主题接口类的一个实例,该实例包含有可以经常发生变化的数据。具体主题需使用一个集合,比如ArrayList,存放观察者的引用,以便数据变化时及时通知具体观察者。
(4)具体观察者(ConcreteObserver):实现抽象观察者角色所需要的更新接口,对具体主题通知做出改变。
通俗点就是:主题发布信息,观察者获取信息,他们关联了就能收到信息,没有关联就收不到信息。
如图:
image.png
观察者模式的适用的场景
如果你想一个对象的数据更新时需要通知其他对象,让其他对象对通知做出改变,那么观察者模式比较实用。
代码部分
场景:假设张三和李四买彩票,时刻关注彩票中心的消息,其中一个人中奖,很高兴,另一个人不开心,取消了对彩票中心的关注,就再也收不到彩票中心的消息了。
在这个模拟中彩票中心就是主题(Subject),张三和李四就是观察彩票中心消息的具体观察者(ConcreteObserver)。对彩票消息做出行为。
Subject接口相关代码
/** * 描述:抽象主题(抽象被观察者) */public interface Subject { /** * 注册观察者 * @param observer 观察者 */ void registerObserver(Observer observer); /** * 移除观察者 * @param observer 观察者 */ void removeObserver(Observer observer); /** * 在状态发生变化通知观察者 */ void notifyObserver(String message); }
Observer接口相关代码
/** * 描述:抽象观察者 */public interface Observer { /** * 当被观察者调用notifyObservers()方法时,观察者的update()方法会被回调。 * @param message 通知内容 */ void update(ConcreteObserver observer,String message); }
ConcreteSubject类相关代码
/** * 描述:具体主题实现类 */public class ConcreteSubject implements Subject { //创建集合用来存放观察者对象 List<Observer> mObserverList; public ConcreteSubject() { mObserverList = new LinkedList<>(); } //注册观察者,也就是将观察者放到集合中 @Override public void registerObserver(Observer observer) { mObserverList.add(observer); } //移除观察者,也就是将观察者从集合中移除 @Override public void removeObserver(Observer observer) { mObserverList.remove(observer); } //状态改变,通知观察者 @Override public void notifyObserver(String message) { //遍历通知所有观察者 for(int i =0;i<mObserverList.size();i++){ //此处进行了强转 mObserverList.get(i).update((ConcreteObserver)mObserverList.get(i),message); } } /** * 通知内容 * @param message */ public void sendMessage(String message){ notifyObserver(message); } }
ConcreteObserver类相关代码
/** * 描述:具体观察者,对Subject的通知执行具体操作 */public class ConcreteObserver implements Observer { private static final String TAG = "ConcreteObserver"; //用户名 String name; //中奖号码 String number; public ConcreteObserver(String name,String work) { this.name = name; this.number=work; } @Override public void update(ConcreteObserver observer,String message) { if(observer.number.equals(message)){ Log.e(TAG, observer.name+"的号码是:" +observer.number+"中奖号码是"+message+"他很高兴"); }else{ Log.e(TAG, observer.name+"的号码是:" +observer.number+"中奖号码是"+message+"不很高兴"); } } }
测试相关代码
//创建主题实例 ConcreteSubject concreteSubject =new ConcreteSubject(); ConcreteObserver zhansan =new ConcreteObserver("张三","111111"); ConcreteObserver lisi =new ConcreteObserver("李四","222222"); concreteSubject.registerObserver(zhansan); concreteSubject.registerObserver(lisi); //设置中奖号码 concreteSubject.sendMessage("111111"); //移除观察者李四 concreteSubject.removeObserver(lisi); //设置中奖号码 concreteSubject.sendMessage("222222");
测试结果:
作者:薛之涛
链接:https://www.jianshu.com/p/cbf47463e0ed
共同学习,写下你的评论
评论加载中...
作者其他优质文章