观察者模式
来源:互联网 发布:sql商务系统开发培训 编辑:程序博客网 时间:2024/06/15 12:18
观察者模式
本文将用报社与订阅报纸人的关系解释观察者模式
这个是发布消息者
package Observer;import java.util.Observable;public class NewsPager extends Observable { private String mName; public NewsPager(String name) { mName = name; } /** * 有新报纸的时候调用Observable类的setChanged方法,表明有更新 * 然后通知订阅过的人 * @param msg 自己定义信息 */ public void sendMsg(String msg) { //表示有更新 setChanged(); //通知注册的观察者 notifyObservers(msg); } public String getName() { return mName; } public void setName(String name) { mName = name; }}
这个是注册的观察者
package Observer;import java.util.Observable;import java.util.Observer;public class Person implements Observer { // 每一个观察者的名字 private String name; public Person(String name) { this.name = name; } /** * 更新回调的方法,有多少观察者就回调多少次 * * @param Observable o 注册的观察者 * @param Object arg 发送的信息 */ public void update(Observable o, Object arg) { NewsPager writer; // 如果发现是NewPager更新的新闻,那就执行下面的操作 if (o instanceof NewsPager) { writer = (NewsPager) o; System.out.println(getName() + " 收到来自 " + writer.getName() + " 的消息: " + arg.toString()); } } public String getName() { return name; } public void setName(String name) { this.name = name; }}
测试
package Observer;/** * 观察者模式测试类 * @author Luo * */public class ObserverTest { public static void main(String[] args) { //创建一个报社 NewsPager newsPager = new NewsPager("人民日报"); //创建两个人 Person a = new Person("龙套A"); Person b = new Person("龙套B"); //有报纸了 newsPager.addObserver(a); newsPager.addObserver(b); //新报纸,赶紧捡肥皂 newsPager.sendMsg("新报纸,赶紧捡肥皂"); }}
现象
龙套B 收到来自 人民日报 的消息: 新报纸,赶紧捡肥皂龙套A 收到来自 人民日报 的消息: 新报纸,赶紧捡肥皂
Observable类(源码)
package java.util;public class Observable { // 数据是否有变化的标志 private boolean changed = false; // 将所有注册的观察者保存在集合中 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); } /** * 通知所有注册过的观察者数据变化了 */ public void notifyObservers() { notifyObservers(null); } /** * 循环通知所有注册过的观察者数据变化了 */ 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; } /** * 返回注册的观察者的数量 * * @return the number of observers of this object. */ public synchronized int countObservers() { return obs.size(); }}
结论
每一个观察者都保存在Observable类的成员变量的集合中,通过将集合转换成数组进行遍历,一个个通知注册的观察者数据有变化。该模式可大大降低代码中的重复逻辑以及类与类之间的耦合性。
1 0
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- IntelliJ IDEA 中如何查看一个类的所有继承关系(当前类的所有继承关系图)
- js窗口震动小程序
- codeforces101156L——Super 2048
- supervisor-进程管理工具
- 添加自定义alias命令
- 观察者模式
- CodeForces 585E
- Junit、Assert、内省、Properties类与配置文件的使用
- C/C++的中缀转后缀并求值的实现
- ViewPager 详解(三)---PagerTabStrip与PagerTitleStrip添加标题栏的异同
- Fast-RCNN代码解读(1)
- HDU 1053 Entropy【哈夫曼编码入门题】
- 一起学opencv(七) 边缘和角点检测
- 【留言板】有问题请在这里留言!