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;
}
@Override
public 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());
}
}
测试截图: