发布订阅模式(观察者模式)

模式的组成结构

抽象主题(Subject)

    它把所有观察者对象的引用保存到一个集合里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象。

具体主题(ConcreteSubject)

   将有关状态存入具体观察者对象;在具体主题内部状态改变时,给所有登记过的观察者发出通知。

抽象观察者(Observer)

   为所有的具体观察者定义一个接口,在得到主题通知时更新自己。

具体观察者(ConcreteObserver)

实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题状态协调。

java代码

抽象(接口主题(发布者))

package com.jlife.pattern.subjecobserver;

/**
 * Created by chen on 2017/3/9.
 * <p>
 * Email 122741482@qq.com
 * <p>
 * Describe: 主题抽象类(接口)
 */
public interface Subject {

    /**
     * 添加观察者
     * @param oberver
     */
    void addObserver(Oberver oberver);

    /**
     * 移除观察者
     * @param oberver
     */
    void removeObserver(Oberver oberver);

    /**
     * 发送消息
     * @param msg
     */
    void sendMessage(String msg);
}

具体主题(发布者)

package com.jlife.pattern.subjecobserver;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by chen on 2017/3/9.
 * <p>
 * Email 122741482@qq.com
 * <p>
 * Describe: 主题实现类
 */
public class SubjectImpl implements Subject {

    private List<Oberver> obervers = new ArrayList<Oberver>();

    @Override
    public void addObserver(Oberver oberver) {
        obervers.add(oberver);
    }

    @Override
    public void removeObserver(Oberver oberver) {
        obervers.remove(oberver);
    }

    @Override
    public void sendMessage(String msg) {
        if (obervers == null || obervers.size() == 0) {
            return;
        }
        for (Oberver oberver : obervers) {
            oberver.update(msg);
        }
    }
}

抽象接口(订阅者,观察者)

package com.jlife.pattern.subjecobserver;

/**
 * Created by chen on 2017/3/9.
 * <p>
 * Email 122741482@qq.com
 * <p>
 * Describe: 订阅者抽象类(接口)
 */
public interface Oberver {
    void update(Object msg);
}

具体(订阅者,观察者)

package com.jlife.pattern.subjecobserver;

/**
 * Created by chen on 2017/3/9.
 * <p>
 * Email 122741482@qq.com
 * <p>
 * Describe:
 */
public class OberverImpl implements Oberver {

    private String name;

    public OberverImpl(String name,Subject subject) {

        this(subject);

        this.name = name;

    }

    public OberverImpl(Subject subject) {
        super();
        subject.addObserver(this);
    }

    public OberverImpl(String name) {
        super();
        this.name = name;
    }

    @Override
    public void update(Object msg) {
        System.out.println(this.name + "============" + msg);
    }
}

测试类

package com.jlife.test.pattern;

import com.jlife.pattern.subjecobserver.Oberver;
import com.jlife.pattern.subjecobserver.OberverImpl;
import com.jlife.pattern.subjecobserver.Subject;
import com.jlife.pattern.subjecobserver.SubjectImpl;
import org.junit.Test;

/**
 * Created by chen on 2017/3/9.
 * <p>
 * Email 122741482@qq.com
 * <p>
 * Describe:
 */
public class SubjectOberver {

    @Test
    public void test() {

        Subject subject = new SubjectImpl();
        Oberver o1 = new OberverImpl("1");
        Oberver o2 = new OberverImpl("2");
        Oberver o3 = new OberverImpl("3");
        Oberver o4 = new OberverImpl("4");
        Oberver o5 = new OberverImpl("5");

        subject.addObserver(o1);
        subject.addObserver(o2);
        subject.addObserver(o3);
        subject.addObserver(o4);
        subject.addObserver(o5);

        subject.sendMessage("woc");
        subject.removeObserver(o3);
        subject.sendMessage("nb");

        Subject subject1 = new SubjectImpl();
        Oberver o6 = new OberverImpl(subject1);
        Oberver o7 = new OberverImpl(subject1);
        Oberver o8 = new OberverImpl(subject1);
        Oberver o9 = new OberverImpl(subject1);
        Oberver o10 = new OberverImpl(subject1);

        subject1.sendMessage("nnnn");

        Subject subject3 = new SubjectImpl();
        Oberver o11 = new OberverImpl("o11",subject3);
        Oberver o12 = new OberverImpl("o12",subject3);
        Oberver o13 = new OberverImpl("o13",subject3);
        Oberver o14 = new OberverImpl("o14",subject3);
        Oberver o15 = new OberverImpl("o15",subject3);

        subject3.sendMessage("sasdsad");
    }
}

运行结果

1============woc
2============woc
3============woc
4============woc
5============woc
1============nb
2============nb
4============nb
5============nb
null============nnnn
null============nnnn
null============nnnn
null============nnnn
null============nnnn
o11============sasdsad
o12============sasdsad
o13============sasdsad
o14============sasdsad
o15============sasdsad

我的官网

我的官网http://guan2ye.com
我的CSDN地址http://blog.csdn.net/chenjianandiyi
我的简书地址http://www.jianshu.com/u/9b5d1921ce34
我的githubhttps://github.com/javanan
我的码云地址https://gitee.com/jamen/
阿里云优惠券https://promotion.aliyun.com/ntms/act/ambassador/sharetouser.html?userCode=vf2b5zld&utm_source=vf2b5zld

阿里云教程系列网站http://aliyun.guan2ye.com

我的开源项目spring boot 搭建的一个企业级快速开发脚手架

时间: 2024-10-29 19:25:03

发布订阅模式(观察者模式)的相关文章

观察者模式与发布/订阅模式区别

在翻阅资料的时候,有人把观察者(Observer)模式等同于发布(Publish)/订阅(Subscribe)模式,也有人认为这两种模式还是存在差异,而我认为确实是存在差异的,本质上的区别是调度的地方不同. 观察者模式 比较概念的解释是,目标和观察者是基类,目标提供维护观察者的一系列方法,观察者提供更新接口.具体观察者和具体目标继承各自的基类,然后具体观察者把自己注册到具体目标里,在具体目标发生变化时候,调度观察者的更新方法. 比如有个"天气中心"的具体目标A,专门监听天气变化,而有个

JavaScript中发布/订阅模式的简单实例

 1.Observer模式要求希望接收到主题通知者的观察者必须订阅内容改变的事件. 2.Subscribe/Publish模式使用了一个主题/事件通道,这个通道介于订阅者和发布者之间.该事件系统允许代码定义应用程序的特定事件,该事件可以传递自定义参数,自定义参数包含订阅者所需要的值.其目的是避免订阅者和发布者产生依赖关系. 与Observer模式不同之处在于它允许任何订阅者执行适当的事件处理程序来注册和接收发布者发出的通知. 好吧,不明觉厉.下面是我的理解: 1.观察者模式中,目标对象负责维护观

JavaScript中发布/订阅模式的简单实例_javascript技巧

上次研究观察者模式,很多文章说它也叫Subscribe/Publish(发布/订阅模式).可在<Javascript设计模式>一书中,这两种模式还是有些区别的.书中原话如下: 1.Observer模式要求希望接收到主题通知者的观察者必须订阅内容改变的事件. 2.Subscribe/Publish模式使用了一个主题/事件通道,这个通道介于订阅者和发布者之间.该事件系统允许代码定义应用程序的特定事件,该事件可以传递自定义参数,自定义参数包含订阅者所需要的值.其目的是避免订阅者和发布者产生依赖关系.

15天玩转redis —— 第九篇 发布/订阅模式

本系列已经过半了,这一篇我们来看看redis好玩的发布订阅模式,其实在很多的MQ产品中都存在这样的一个模式,我们常听到的一个例子 就是邮件订阅的场景,什么意思呢,也就是说100个人订阅了你的博客,如果博主发表了文章,那么100个人就会同时收到通知邮件,除了这个 场景还能找到其他场景么,当然有啦,你想想,如果你要在内存里面做一个读写分离的程序,为了维持数据的完整性,你是不是需要保证在写入 的时候,也要分发到各个读内存的程序中呢?所以说场景还是很多的,在于你的挖掘~~~ 下面还是从基本命令入手: 一

Redis的发布订阅模式

发布和订阅机制 当一个客户端通过 PUBLISH 命令向订阅者发送信息的时候,我们称这个客户端为发布者(publisher). 而当一个客户端使用 SUBSCRIBE 或者 PSUBSCRIBE 命令接收信息的时候,我们称这个客户端为订阅者(subscriber). 为了解耦发布者(publisher)和订阅者(subscriber)之间的关系,Redis 使用了 channel (频道)作为两者的中介 -- 发布者将信息直接发布给 channel ,而 channel 负责将信息发送给适当的订

EventBus实现、发布订阅及XML加载

受到CQRS的影响,写了个EventBus,能实现发布订阅模式执行event,在DDD模 型中,可以使用如下代码触发事件: EventBus bus = EventBus.Instance(); bus.Publish(new OrderAddedEvent()); 解决方案结构图如下,很简单易懂: xml事件配置代码sample如下(1个event可以定义多个订阅者,如下): <?xml version="1.0" encoding="utf-8" ?>

Redis开发与运维. 3.7 发布订阅

3.7 发布订阅 Redis提供了基于"发布/订阅"模式的消息机制,此种模式下,消息发布者和订阅者不进行直接通信,发布者客户端向指定的频道(channel)发布消息,订阅该频道的每个客户端都可以收到该消息,如图3-16所示.Redis提供了若干命令支持该功能,在实际应用开发时,能够为此类问题提供实现方法.   图3-16 Redis发布订阅模型 3.7.1 命令 Redis主要提供了发布消息.订阅频道.取消订阅以及按照模式订阅和取消订阅等命令. 1.?发布消息 publish chan

消息队列中点对点与发布订阅区别(good)

背景知识 JMS一个在 Java标准化组织(JCP)内开发的标准(代号JSR 914).2001年6月25日,Java消息服务发布JMS 1.0.2b,2002年3月18日Java消息服务发布 1.1. Java消息服务(Java Message Service,JMS)应用程序接口是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信. 点对点与发布订阅最初是由JMS定义的.这两种模式主要区别或解决的问题就是发送到队列的消息能否重

分享一个分布式消息总线,基于.NET Socket Tcp的发布-订阅框架,附代码下载

一.分布式消息总线      在很多MIS项目之中都有这样的需求,需要一个及时.高效的的通知机制,即比如当使用者A完成了任务X,就需要立即告知使用者B任务X已经完成,在通常的情况下,开发人中都是在使用者B所使用的程序之中写数据库轮循代码,这样就会产品一个很严重的两个问题,第一个问题是延迟,轮循机制要定时执行,必须会引起延迟,第二个问题是数据库压力过大,当进行高频度的轮循会生产大量的数据库查询,并且如果有大量的使用者进行轮循,那数据库的压力就更大了.      那么在这个时间,就需要一套能支持发布