美文网首页@IT·互联网想法
设计模式之观察者模式,你我都是发布者和订阅者

设计模式之观察者模式,你我都是发布者和订阅者

作者: java程序员思维 | 来源:发表于2019-04-27 20:22 被阅读13次

观察者模式

观察者模式(又被称为发布-订阅(Publish/Subscribe)模式,属于行为型模式的一种,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己。

观察者模式四大角色

Subject:抽象主题(抽象被观察者),抽象主题角色把所有观察者对象保存在一个集合里,每个主题都可以有任意数量的观察者,抽象主题提供新增、删除、通知观察者的方法。

ConcreteSubject:具体主题(具体被观察者),该角色将有关状态存入具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知。

Observer:抽象观察者,是观察者者的抽象类,它定义了一个更新接口,使得在得到主题更改通知时更新自己。

ConcrereObserver:具体观察者,实现抽象观察者定义的更新接口,以便在得到主题更改通知时更新

使用场景

商品变更的时候,需要更新商品缓存、发布商品详情页、更新搜索索引,传统做法,在商品update方法处,分别调用更新商品缓存接口、发布商品接口、更新搜索索引接口。代码耦合度很高,如果增加一个新的逻辑,需要修改update方法,如果商品修改不需要更新缓存了,同样需要修改update方法。通过引入观察者模式,通过消息中间件的方式可以进行解耦,当商品发生修改的时候,发送一个消息,商品缓存应用可以订阅此消息,进行缓存的更新。商品发布系统,订阅此消息,重新发布商品。搜索应用,订阅此消息,增量更新索引。

如果商品更改有其他的业务逻辑,可以通过消息订阅和消费,增加相应的逻辑。如果要去掉某个逻辑,只要取消消息订阅,不再消费此消息即可。观察者模式通过发布和订阅的方式,实现业务的解耦。

代码实现

public interface Subject{

//添加观察者

void addObserver(Observer obj);

//移除观察者

void deleteObserver(Observer obj);

//当主题方法改变时,这个方法被调用,通知所有的观察者

void notifyObserver();

}

public class StudentObserver implements Observer{

//保存一个Subject的引用,以后如果可以想取消订阅,有了这个引用会比较方便

private Subject subject;

//学生的姓名,用来标识不同的学生对象

private String name;

//构造器用来注册观察者

public Student Observer(String name,TeacherSubject teacherSubject) {

this.name=name;

this.subject = teacherSubject;

//每新建一个学生对象,默认添加到观察者的行列

teacherSubject.addObserver(this);

}

public void update(Stringinfo) {

System.out.println(name+"得到作业:"+info);

}

}

public interface Subject{

//添加观察者

void addObserver(Observer obj);

//移除观察者

void removeObserver(Observer obj);

//当主题方法改变时,这个方法被调用,通知所有的观察者

void notifyObserver();

}

public class StudentObserver implements Observer{

//保存一个Subject的引用,以后如果可以想取消订阅,有了这个引用会比较方便

private Subject subject;

//学生的姓名,用来标识不同的学生对象

private String name;

//构造器用来注册观察者

public StudentObserver(String name,TeacherSubject teacherSubject) {

this.name=name;

this.subject = teacherSubject;

//每新建一个学生对象,默认添加到观察者的行列

teacherSubject.addObserver(this);

}

public void update(Stringinfo) {

System.out.println(name+"得到作业:"+info);

}

}

public classTestObserver{

public static void main(String[] args) {

TeacherSubject teacher =newTeacherSubject();

StudentObserver zhangSan =newStudentObserver("张三", teacher);

StudentObserver LiSi =newStudentObserver("李四", teacher);

StudentObserver WangWu =newStudentObserver("王五", teacher);

teacher.setHomework("第二页第六题");

System.out.println("----------------");

teacher.setHomework("第三页第七题");

System.out.println("----------------");

teacher.setHomework("第五页第八题");

}

}

运行结果:

代码不是特别的严谨,没有考虑多线程问题,不是线程安全的,用于生产环境,需要做同步或者增加锁控制。java中jdk提供了相关的工具类,java.uitl包下的Observer和Observable,这个是同步的,支持多线程。java自带jdk实现方法如下:

public class Message {

private String title;

private String 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 Message(String title,String content) {

this.title = title;

this.content = content;

}

@Override

public String toString() {

return"Message{"+

"title='"+ title +'\''+

", content='"+ content +'\''+

'}';

}

}

//订阅者

public class MessageObserver implementsObserver{

private String title;

public String getTitle(){

return title;

}

public void setTitle(String title){

this.title = title;

}

public MessageObserver(String title){

this.title = title;

}

public void update(Observable o, Object arg){

System.out.println("observer :"+ title +",receive a message"+ arg.toString());

}

}

//发布者

public class MessagePublishObservable extends Observable{

private Message message;

public MessagePublishObservable(Message message){

this.message = message;

}

public void pushMessage(){

setChanged();

notifyObservers(message);

}

public Message getMessage(){

return message;

}

public void setMessage(Message message){

this.message = message;

}

@Override

public synchronized void addObserver(Observer o){

super.addObserver(o);

}

@Override

public synchronized void deleteObserver(Observer o){

super.deleteObserver(o);

}

@Override

public void notifyObservers(){

super.notifyObservers();

}

@Override

public void notifyObservers(Object arg){

super.notifyObservers(arg);

}

@Override

protected synchronized void setChanged(){

super.setChanged();

}

}

public classTest{

public static void main(String[] args){

MessageObserver messageObserverTopicA =new MessageObserver("A");

MessageObserver messageObserverTopicB =new MessageObserver("B");

MessageObserver messageObserverTopicC =new MessageObserver("C");

MessagePublishObservable messagePublishObservable =new MessagePublishObservable(newMessage("关注","欢迎关注享知行"));

//a关注了享知行

messagePublishObservable.addObserver(messageObserverTopicA);

//b关注了享知行

messagePublishObservable.addObserver(messageObserverTopicB);

//c关注了享知行

messagePublishObservable.addObserver(messageObserverTopicC);

messagePublishObservable.pushMessage();

messagePublishObservable.setMessage(newMessage("文章更新","公众号享知行更新啦"));

messagePublishObservable.pushMessage();

}

}

运行结果:

优缺点

优点:发布者和订阅者是松耦合的,发布者和订阅者之间互不影响,满足开闭原则,当有变化的时候,实时,高效的通知订阅者。

缺点:如果一个发布者对象有很多直接和间接的订阅者的话,将所有的订阅者都通知到会花费很多时间。如果在发布者之间有循环依赖的话,发布者会触发它们之间进行循环调用,导致系统崩溃。

生活中的观察者模式

老师布置作业,采用的就是观察者模式,老师是信息的发布者,学生是订阅者,老师布置作业只需要布置一遍即可,所有的学生,都能收到这个任务。

邮件组也是观察者模式,可以动态的增加和删除组成员,技术部的所有成员创建一个邮件组,如果需要发送邮件通知所有技术部的人,只要发送一封邮件给技术部邮件组即可,既方便又不会遗漏。如果有员工入职加入邮件组,有员工离职则从邮件组删除。

群社区也是观察者模式的一种形式,有相同爱好兴趣的人加入到同一个群,每一个人既是消息的发布者,也是订阅者,让大家的沟通更实时高效。

专栏的订阅,公众号的关注也是属于观察者模式,内容生产者,有新的内容更新,会通知所有的订阅者,你如果喜欢“享知行”,并关注了公众号“享知行”,只要享知行有内容更新,会通知所有的粉丝。

直播和视频,同样也是观察者模式,内容生产者,直播或者把录好的视频上传,如果你感兴趣,点开观看,所有人看到的都是同样的内容。

app消息订阅、报纸订阅、新闻订阅等等都是观察者模式,观察者模式无处不在,我们既是内容生产者也是内容的消费者。

我的启发

我们既是内容的生产者,不断的创造内容。作为内容的生产者,请保持内容的质量。我们也是内容的消费者,不断的消费内容,作为内容的消费者,请保持批判的精神。

相关文章

  • 观察者模式js实现

    参看书籍JavaScript模式第七章设计模式我的理解:观察者模式又叫订阅/发布模式。被观察者(发布者)内部需要有...

  • js设计模式(一)

    单例模式: 目的是创建全局唯一可用的对象 订阅-发布者模式 (观察者模式) 观察者模式又叫发布订阅模式(Publi...

  • 设计模式之观察者模式,你我都是发布者和订阅者

    观察者模式 观察者模式(又被称为发布-订阅(Publish/Subscribe)模式,属于行为型模式的一种,它定义...

  • JS-简单实现发布订阅模式

    发布订阅模式主要涉及三个对象:发布者、订阅者、主题对象。 发布-订阅模式 定义  发布-订阅模式又称观察者模式,它...

  • Swift-观察者模式

    观察者模式也可以叫发布订阅模式,观察者有的时候不一定能准备表达观察者模式,主要包括订阅者和发布者,状态事件处理,关...

  • 观察者模式和订阅发布模式

    观察者模式和发布/订阅模式的区别是: ,最大的区别是调度的地方。虽然两种模式都存在订阅者和发布者(具体观察者可认为...

  • 订阅者模式和观察者模式区别

    订阅者模式:角色分类 1、订阅者 2、订阅处理中心 3、发布者 观察者模式:角色分类 1、观察者 2、目标(被观察...

  • Javaの设计模式之观察者模式

    推荐阅读:《设计模式之禅》 Observer Pattern 设计模式之观察者模式(发布订阅模式) Demo gi...

  • 观察者模式

    1、观察者模式,个人理解为发布/订阅关系。订阅者为观察者,发布者为被观察者。同时观察者模式jdk提供了自带的版本。...

  • 观察者设计模式

    观察者设计模式是一个好的设计模式,这个模式我们在开发中比较常见,尤其是它的变形模式订阅/发布者模式我们更是很熟悉,...

网友评论

    本文标题:设计模式之观察者模式,你我都是发布者和订阅者

    本文链接:https://www.haomeiwen.com/subject/brklnqtx.html