观察者模式定义
观察者模式就当多个对象对一个对象存在依赖的时候,这个对象状态的改变需要通知到其他对象的时候,就会用到观察者模式。
观察者模式的好
观察者和被观察者是抽象耦合的
观察者模式主要的类
1.抽象主题(Subject)角色:也叫抽象目标类,它提供了一个用于保存观察者对象的聚集类和增加、删除观察者对象的方法,以及通知所有观察者的抽象方法。
2.具体主题(Concrete Subject)角色:也叫具体目标类,它实现抽象目标中的通知方法,当具体主题的内部状态发生改变时,通知所有注册过的观察者对象。
3.抽象观察者(Observer)角色:它是一个抽象类或接口,它包含了一个更新自己的抽象方法,当接到具体主题的更改通知时被调用。
4.具体观察者(Concrete Observer)角色:实现抽象观察者中定义的抽象方法,以便在得到目标的更改通知时更新自身的状态。
观察者模式的结构图
粉丝作为观察者,粉丝关注博主的博客,博主负责更新文章然后粉丝收到通知,实现:
/**
*
* @ClassName: Observer
* @Description: 抽象观察者
* @author: ljx
* @date: 2019年4月2日 上午10:22:47
*/
public interface Observer {
//更新
public void update(String article);
}
/**
*
* @ClassName: Fans
* @Description: 具体观察者:粉丝
* @author: ljx
* @date: 2019年4月2日 上午10:25:37
*/
public class Fans implements Observer {
@Override
public void update(String article) {
System.out.println("你关注的博主更新文章了 !文章为 :" + article);
}
}
/**
*
* @ClassName: Fans
* @Description: 具体观察者:粉丝2
* @author: ljx
* @date: 2019年4月2日 上午10:25:37
*/
public class Fans2 implements Observer{
@Override
public void update(String article) {
System.out.println("你关注的博主更新文章了 !文章为 :" + article);
}
}
/**
*
* @ClassName: Subject
* @Description: 抽象主题角色
* @author: ljx
* @date: 2019年4月2日 上午10:30:30
*/
public abstract class Subject {
//存放所有观察者对象
List<Observer> list = new ArrayList<Observer>();
/**
*
* @Title: addObserver
* @Description: 添加观察者
* @param observer
* @return: void
*/
public void addObserver(Observer observer){
list.add(observer);
}
/**
*
* @Title: removeObserver
* @Description: 移除观察者
* @param observer
* @return: void
*/
public void removeObserver(Observer observer){
list.remove(observer);
}
/**
*
* @Title: nodifyObserver
* @Description: 通知所有观察者
* @param article
* @return: void
*/
public void nodifyObserver(String article){
for (Observer observer : list) {
observer.update(article);
}
}
}
/**
*
* @ClassName: Article
* @Description: 具体主题角色:作者
* @author: ljx
* @date: 2019年4月2日 上午10:39:55
*/
public class Article extends Subject {
private String article;
public String getArticle() {
return article;
}
public void setArticle(String article) {
this.article = article;
//通知观察者
this.nodifyObserver(article);
}
}
public class ObserverTest {
public static void main(String[] args) {
//创建主题
Article article = new Article();
//创建观察者
Observer fans = new Fans();
Observer fans2 = new Fans2();
//创建观察者
article.addObserver(fans);
article.addObserver(fans2);
article.setArticle("今天发微博");
}
}
输出结果
你关注的博主更新文章了 !文章为 :今天发微博
你关注的博主更新文章了 !文章为 :今天发微博
在Spring中也有事件发布和事件监听,这也是应用到了观察者,ApplicationContext 中事件处理是由 ApplicationEvent 类和 ApplicationListener 接口来提供的。如果一个Bean实现了 ApplicationListener 接口,并且已经发布到容器中去,每次 ApplicationContext 发布一个 ApplicationEvent 事件,这个Bean就会接到通知
ApplicationContext:事件源,其中的 publishEvent()方法用于触发容器事件
ApplicationEvent:事件本身,自定义事件需要继承该类,可以用来传递数据
ApplicationListener:事件监听器接口,事件的业务逻辑封装在监听器里面
@SpringBootTest
@RunWith(SpringRunner.class)
public class SpringListennerTest {
@Autowired
private ApplicationContext ctx;
@Test
public void test() {
SpringExventStar springExventStar = new SpringExventStar(ctx,"王菲谢霆锋","世纪大复合");
ctx.publishEvent(springExventStar);
}
}
/**
* 事件
*/
class SpringExventStar extends ApplicationEvent {
private String name;
private String event;
public SpringExventStar(Object source,String name,String event){
super(source);
this.name=name;
this.event=event;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEvent() {
return event;
}
public void setEvent(String event) {
this.event = event;
}
}
class SpringListennerStar implements ApplicationListener{
@Override
public void onApplicationEvent(ApplicationEvent var1){
if(var1 instanceof SpringExventStar){
SpringExventStar event = (SpringExventStar)var1;
System.out.println("明星"+event.getName()+"发生了"+event.getEvent());
}
}
}
@Configuration
class SpringListennerConfiguration{
@Bean
public SpringListennerStar getSpringListennerStar(){
return new SpringListennerStar();
}
}
最后输出:
明星王菲谢霆锋发生了世纪大复合
这次也算弄清楚了spring中的事件监听机制,这个在springboot中被常用到。
参考文章:
https://blog.csdn.net/wwwdc1012/article/details/83317973?spm=1001.2014.3001.5501
https://blog.csdn.net/qq594913801/article/details/88964178?spm=1001.2014.3001.5501