Java内置的观察者模式的使用

来源:互联网 发布:电气图设计软件 编辑:程序博客网 时间:2024/05/29 09:35

Java已经内置了观察者模式的观察者模式,我们可以直接拿来用,并不需要我们在重写了。

Java API 有可观察者接口也就是主题接口 和 观察者接口,分别是

1、java.util.Observable 可观察的 也就是 主题, 是一个抽象类。下面是它的API,源码也很容易看懂。


2、java.util.Observer 观察者接口


使用也很简单,注意的是在 通知观察者之前 必须先调用setChanged 改变主题状态,才会去通知观察者。

下面看个简单例子,新闻 主题 和看新闻的观察者 ,一旦新闻更新了 观察者就会得到通知。

新闻主题

package com.lcx.designpattern.observerpattern;import java.util.Date;import java.util.Observable;/** *  * 新闻主题对象,当新闻消息改变时,通知所有观察者 * @author  * */public class NewsObservable extends Observable {private String newsMsg;public String getNewsMsg() {return newsMsg;}public NewsObservable() {super();}/** * 设置新消息,通知观察者 * @param newsMsg 新消息 */public void setNewsMsg(String newsMsg) {this.newsMsg = newsMsg;setChanged();//改变状态才能通知观察者notifyObservers();}/** * 设置新消息,并传递数据对象 * @param newsMsg 新消息 * @param date 数据对象 此时数据对象为时间 */public void setNewsMsg(String newsMsg,Date date) {this.newsMsg = newsMsg;setChanged();notifyObservers(date);}}

观察者以及测试代码

package com.lcx.designpattern.observerpattern;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Observable;import java.util.Observer;/** * 看新闻的观察者 * @author  * */public class Person implements Observer {private String name;public Person(String name) {super();this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic void update(Observable o, Object arg) {if(o instanceof NewsObservable){NewsObservable news = (NewsObservable) o;Date date = (Date) arg;SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");String dateStr = format.format(date);System.out.println(dateStr+","+name+"看新闻:"+news.getNewsMsg());}}public static void main(String[] args) {        //创建新闻主题NewsObservable news = new NewsObservable();//创建看新闻的观察者Person p1 = new Person("张三");Person p2 = new Person("李四");Person p3 = new Person("王五");//订阅新闻news.addObserver(p1);news.addObserver(p2);news.addObserver(p3);//出新闻了news.setNewsMsg("隔壁老王和寡妇张恋爱了!", new Date());news.setNewsMsg("中国第三艘航母起航啦",new Date());}}

测试截图: