观察者模式
观察者模式定义了对象之间的一对多依赖,让多个观察者同时监听某个主题对象,当主体对象发生变化时,它的所有观察者都会收到响应的通知。
优点:
观察者和被观察者之间建立一个抽象的耦合;
目标与观察者之间建立了一套触发机制
观察者模式支持广播通信。
缺点:
当观察者对象很多时,通知的发布会花费很多时间,影响程序的效率
观察者之间有过多的细节依赖,提高时间消耗及程序复杂度;
应避免循环调用。
观察者模式适合以下几种情形。
1.对象间存在一对多关系,一个对象的状态发生改变会影响其他对象。
2.当一个抽象模型有两个方面,其中一个方面依赖于另一方面时,可将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
观察者模式的主要角色如下。
抽象主题(Subject)角色:也叫抽象目标类,它提供了一个用于保存观察者对象的聚集类和增加、删除观察者对象的方法,以及通知所有观察者的抽象方法。
具体主题(Concrete Subject)角色:也叫具体目标类,它实现抽象目标中的通知方法,当具体主题的内部状态发生改变时,通知所有注册过的观察者对象。
抽象观察者(Observer)角色:它是一个抽象类或接口,它包含了一个更新自己的抽象方法,当接到具体主题的更改通知时被调用。
具体观察者(Concrete Observer)角色:实现抽象观察者中定义的抽象方法,以便在得到目标的更改通知时更新自身的状态。
1.创建一个评论类,里面有评论人名和内容
public class Comment {
private String name;
private String info;
public String getName() {
return name;
}
public Comment(String name, String info) {
this.name = name;
this.info = info;
}
public void setName(String name) {
this.name = name;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
}
2.创建一个博客类,需要继承JDK的Observable类,成为被观察对象
注意要设置标识位 changed = true,表示被观察者发生了改变,然后用 notifyObservers(comment);通知观察者,也可以给观察者传递数据,这样才能被系统观察到变化,被观察者对象包含如下属性和方法:
public class Blog extends Observable {
private String title;
public Blog(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
public void comment(Comment comment){
System.out.println(comment.getName()+"评论了"+this.title+" 评论内容为:"+comment.getInfo());
// 设置标识位 changed = true,表示被观察者发生了改变
setChanged();
// 通知观察者,可以给观察者传递数据
notifyObservers(comment);
}
}
3.创建一个作者类,里面有个作者名的属性,要实现Observer 接口,才能成为观察者
public class Author implements Observer {
private String name;
public Author(String name) {
this.name = name;
}
/**
* 观察者被通知后,就会调用这个方法
*
* @param o 被观察者对象
* @param arg 被观察者传递过来的数据
*/
@Override
public void update(Observable o, Object arg) {
Blog blog=(Blog)o;
Comment comment=(Comment)arg;
System.out.println("系统通知:"+this.name+"写的"+blog.getTitle()+"被"+comment.getName()+"评论了,评论内容为:"+comment.getInfo());
}
}
4.测试输出
public class Test {
public static void main(String[] args) {
Blog blob=new Blog("设计模式");
Author author=new Author("javafg");
blob.addObserver(author);
Comment comment=new Comment("小王","优秀,给你点个赞");
blob.comment(comment);
}
}
//小王评论了设计模式 评论内容为:优秀,给你点个赞
//系统通知:javafg写的设计模式被小王评论了,评论内容为:优秀,给你点个赞