@(JAVA开发)
观察者模式可以理解为报纸和杂志的订阅,报社负责给订阅的用户送报纸,只要你订阅了,就会收到报纸,而你不想要了,取消订阅,就不会受到新的报纸。
不针对具体实现编程
把会改变的地方封装起来
应用场景
出版者+ 订阅者= 观察者模式
出版者成为主题
订阅者成为观察者
定义
观察者模式 : 定义了对象之间的一对多依赖,这样一来,当一个对象改变状态的时候,它的所有依赖者都会收到通知并且自动更新。
事例
这次我用了报纸和订阅来做例子
首先是报纸实体类
public class NewPaper {
private String title;
private String content;
private Date date;
public NewPaper(String title,String content){
this.title=title;
this.content=content;
this.date=new Date();
}
public void readPaper(){
System.out.println("今天是:"+date.toString()+"头条是:"+title+"内容是:"+content);
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
}
观察者接口,所有的观察者都要实现接收送到的报纸
/**
* 观察者接口
* @author kan
*
*/
public interface Observer {
public void sendNewPaper(NewPaper paper);
}
主题接口 ,里面包含了注册观察者,移除观察者和通知观察者的方法
public interface Subject {
public void regisiterObserver(Observer observer);
public void removeObserver(Observer observer);
public void notifyObserver();
}
实现观察者接口的几个类,当然叫名字不是很恰当,大家意思明白就好了。
public class Jerry implements Observer{
@Override
public void sendNewPaper(NewPaper paper) {
System.out.println("jerry读报");
paper.readPaper();
}
}
public class Tom implements Observer {
@Override
public void sendNewPaper(NewPaper paper) {
System.out.println("tom读报:");
paper.readPaper();
}
}
实现主题接口的报社类
public class NewPaperOffice implements Subject {
private ArrayList<Observer> observers;
private NewPaper newPaper;
public NewPaperOffice(){
observers=new ArrayList<Observer>();
}
public void setNewPaper(NewPaper newPaper) {
this.newPaper = newPaper;
}
public void hasNewPaper(){
notifyObserver();
}
@Override
public void regisiterObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
int i=observers.indexOf(observer);
if(i>=0){
observers.remove(i);
}
}
@Override
public void notifyObserver() {
for (int i = 0; i < observers.size(); i++) {
Observer observer=observers.get(i);
observer.sendNewPaper(newPaper);
}
}
最后测试用的test
public class TestPaper {
public static void main(String[] args) {
NewPaper paper1 =new NewPaper("大暴雨北京","北京今日持续暴雨,导致路面瘫痪");
NewPaper paper2 =new NewPaper("晴天了","北京今日晴天,大家都出来晒太阳");
NewPaper paper3 =new NewPaper("下雪了北京","下雪了以后北京很漂亮");
NewPaperOffice newPaperOffice=new NewPaperOffice();
newPaperOffice.setNewPaper(paper1);
Tom tom=new Tom();
Lilei lilei=new Lilei();
Jerry jerry=new Jerry();
newPaperOffice.regisiterObserver(tom);
newPaperOffice.regisiterObserver(lilei);
newPaperOffice.regisiterObserver(jerry);
newPaperOffice.hasNewPaper();
System.out.println("tom不订阅了");
newPaperOffice.removeObserver(tom);
newPaperOffice.setNewPaper(paper2);
newPaperOffice.hasNewPaper();
System.out.println("tom又来订阅了");
newPaperOffice.regisiterObserver(tom);
newPaperOffice.setNewPaper(paper3);
newPaperOffice.hasNewPaper();
}
运行结果如下图:
**tom读报:
今天是:Thu Jul 21 23:57:31 CST 2016头条是:大暴雨北京内容是:北京今日持续暴雨,导致路面瘫痪
李磊读报
今天是:Thu Jul 21 23:57:31 CST 2016头条是:大暴雨北京内容是:北京今日持续暴雨,导致路面瘫痪
jerry读报
今天是:Thu Jul 21 23:57:31 CST 2016头条是:大暴雨北京内容是:北京今日持续暴雨,导致路面瘫痪
tom不订阅了
李磊读报
今天是:Thu Jul 21 23:57:31 CST 2016头条是:晴天了内容是:北京今日晴天,大家都出来晒太阳
jerry读报
今天是:Thu Jul 21 23:57:31 CST 2016头条是:晴天了内容是:北京今日晴天,大家都出来晒太阳
tom又来订阅了
李磊读报
今天是:Thu Jul 21 23:57:31 CST 2016头条是:下雪了北京内容是:下雪了以后北京很漂亮
jerry读报
今天是:Thu Jul 21 23:57:31 CST 2016头条是:下雪了北京内容是:下雪了以后北京很漂亮
tom读报:
今天是:Thu Jul 21 23:57:31 CST 2016头条是:下雪了北京内容是:下雪了以后北京很漂亮**
总结
从结果上来看,观察者模式很好的做到了松耦合,订阅者的增加和移除都不涉及到主题和报社代码的更改,更加易于维护和扩展。
当然,这是我自己实现的观察者模式,java本身也有内置的观察者模式。
util 包里面包含了基本的Oberver 接口和 Observable 类,其使用我将会专门写一篇和自己实现的作比较。