主要内容:
1. 概念
当实体间存在某种一对多关系,即当一方发生改变,依赖于它的实体将收到通知这样的事件,也就是观
察者模式,俗称发布订阅,也常被人称作监听器模式。但是不论怎么称呼它只属于行为型的设计模式。
观察者模式两个概念:被观察者(1)、观察者(N),为了更方便理解,我们将被观察者比作一个工
厂,观察者比作每个消费者。所以我们在设计开发需要注意这两个对象。下来我们将利用JDK自带的方
式来编写用例,同时我们还穿插多线程方式的实现。
1.1. 简介分析
使用场景:适合构建关联场景,例如一个对象(目标对象)的状态发生改变,所有的依赖对象(观
察者对象)都将得到通知,进行广播通知。
解决方式:使用面向对象技术,可以将这种依赖关系弱化。
举个栗子:
粉丝订阅大V的博主
博主发布微博文章。
粉丝们收到博主的发布
1.2. 优缺点
1.2.1. 优点
观察者和被观察者是抽象耦合的。
建立一套触发机制。
1.2.2. 缺点
如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时
间
如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致
系统崩溃
观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观
察目标发生了变化。
2. 2.2.单线程同步实现
JAVA 中已经有了对观察者模式的支持类,这次我们直接使用。
2.1. 观察者 import lombok.extern.slf4j.Slf4j; import java.util.Observable; import java.util.Observer; /*** @ClassName Fan * @Description 观察者 * @author [email protected] * @Github https://github.com/rothschil * @date 2019/12/25 16:36 * @Version 1.0.0 */@Slf4j public class Fan implements Observer { private String fanName; @Override public void update(Observable o, Object arg) { Blogger blogger=(Blogger)o; Article article=(Article)arg; log.error("粉丝{},看见{}的博主发表主题为{}的微博,内容为{}",fanName,blogger.getBlogName(),article.getTopicNa }public Fan(String fanName) { this.fanName = fanName; } }
2.2. 被观察者
package xyz.wongs.weathertop.design.observer; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import java.util.Observable; /*** @ClassName Blogger * @Description 被观察者,对观察者对象的引用进行抽象保存 * @author [email protected] * @Github https://github.com/rothschil * @date 2019/12/25 16:36 * @Version 1.0.0 */@Slf4j public class Blogger extends Observable { @Getter private String blogName; public Blogger(String blogName) { this.blogName = blogName; }public void productArticle(Blogger blogger,Article article){ log.error("博主{}发表主题为{}的微博",blogger.getBlogName(),article.getTopicName()); setChanged(); notifyObservers(article); } }
2.3. 观察的目标
package xyz.wongs.weathertop.design.observer; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @AllArgsConstructor @NoArgsConstructor @Data public class Article { private String topicName; private String context;