文档章节

设计模式-观察者模式(发布订阅模式)

月夜筱风
 月夜筱风
发布于 2017/08/30 18:17
字数 1023
阅读 34
收藏 0

一,定义

输入图片说明

二,普通版本代码(实际用处不大)

  • 2.1目录

输入图片说明

  • 2.2代码
package com.boot.lijunhao.guanchazhemoshi;

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

/**
 * Created by lijunhao on 2017/8/30.
 */
public abstract class Subject {

    //订阅的抽象类,中会包含一些被观察者(也是一个接口或抽象类)
    private List<Observer> observerList=new ArrayList <>();

    //增加被观察者
    void addObserver(Observer observer){
        observerList.add(observer);
    }

    //删除被观察者
    void deleteObserver(Observer observer){
        observerList.removeIf(t->t.equals(observer));
    }

    //通知所有被观察者的变化接口
    void notifyMethod(){
        observerList.forEach(t ->t.getStateMethod());
    }

}

package com.boot.lijunhao.guanchazhemoshi;

import lombok.extern.slf4j.Slf4j;

/**
 * 具体需要监控的属性都写在具体类中
 * Created by lijunhao on 2017/8/30.
 */
@Slf4j
public class RelatedSubject extends Subject {

    private String state;

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }
}

package com.boot.lijunhao.guanchazhemoshi;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;

/**
 *
 * 相关的被观察类
 * Created by lijunhao on 2017/8/30.
 */
@Slf4j
@Data
public class RelatedObserver implements Observer {
    //这个可以确定被观察者的id
    private String name;

    //就是对RelatedSubject中相关属性的监视属性(这个值其实是从RelatedSubject取出的state)
    private String state;

    //从这个里面是拿到所被监视的属性,并对变化做出响应
    private RelatedSubject relatedSubject;

    public RelatedObserver(String name, RelatedSubject relatedSubject) {
        this.name = name;
        this.relatedSubject = relatedSubject;
    }

    @Override
    public void getStateMethod() {
        state =  relatedSubject.getState();
        log.info("getState在类(RelatedObserver.java:24)行:{}",name+"的新的状态是"+state);
    }



}

package com.boot.lijunhao.guanchazhemoshi;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;

/**
 * 同Relatedbserver,getStateMethod中可以做不同的修改
 * Created by lijunhao on 2017/8/30.
 */
@Slf4j
@Data
public class Related2Observer implements Observer {

    private String name;

    private String state;

    private RelatedSubject relatedSubject;

    public Related2Observer(String name, RelatedSubject relatedSubject) {
        this.name = name;
        this.relatedSubject = relatedSubject;
    }

    @Override
    public void getStateMethod() {
        state =  relatedSubject.getState();
        log.info("getState在类(Related2Observer.java:24)行:{}","另外一个类中的"+name+"的新的状态是"+state);
    }



}

package com.boot.lijunhao.guanchazhemoshi;

/**
 * 被观察者的抽象类中被监视的方法
 * Created by lijunhao on 2017/8/30.
 */
public interface Observer {

    //被监视的方法
    void getStateMethod();
}

package com.boot.lijunhao.guanchazhemoshi;

/**
 * Created by lijunhao on 2017/8/30.
 */
public class Start {

    public static void main(String[] args) {

        RelatedSubject relatedSubject = new RelatedSubject();
        //new RelatedObserver("C",relatedSubject),确定的是C->id和relatedSubject
        relatedSubject.addObserver(new RelatedObserver("C",relatedSubject));
        relatedSubject.addObserver(new RelatedObserver("X",relatedSubject));
        RelatedObserver d = new RelatedObserver("D", relatedSubject);
        Related2Observer e = new Related2Observer("E", relatedSubject);
        relatedSubject.addObserver(e);
        //可以增加被观察者
        relatedSubject.addObserver(d);
        //可以删除被观察者
        relatedSubject.deleteObserver(d);
        //在Subject中设置新的状态
        relatedSubject.setState("新状态");
        //通知方法中
        relatedSubject.notifyMethod();
    }

}

  • 2.3,结果
13:42:11.587 [main] INFO com.boot.lijunhao.guanchazhemoshi.RelatedObserver - getState在类(RelatedObserver.java:24)行:C的新的状态是新状态
13:42:11.602 [main] INFO com.boot.lijunhao.guanchazhemoshi.RelatedObserver - getState在类(RelatedObserver.java:24)行:X的新的状态是新状态
13:42:11.602 [main] INFO com.boot.lijunhao.guanchazhemoshi.Related2Observer - getState在类(Related2Observer.java:24)行:另外一个类中的E的新的状态是新状态

三,java自带版本

3.1 在Java中通过Observable类和Observer接口实现了观察者模式

输入图片说明

  • 3.2 代码
package com.boot.lijunhao.guanchazhemoshi;

import java.util.Observable;

/**
 * Created by lijunhao on 2017/8/31.
 */
public class JavaObserver extends Observable {
    //被监视的属性
    private String state;

    public String getState() {
        return state;
    }

    public void setState(String state) {
        //每次set改变的时候就调用setChanged()和notifyObservers()去通知所有观察者,然后去执行他们的update方法
        this.state = state;
        int j = countObservers();

        System.out.println("1"+j);
        //告诉被改变了
        setChanged();
        int i = countObservers();
        System.out.println("1"+i);
        //通知所有的观察者
        notifyObservers();
    }
}

package com.boot.lijunhao.guanchazhemoshi;

import java.util.Observable;

/**
 * 同JavaObserver的作用
 * Created by lijunhao on 2017/8/31.
 */
public class JavaObserver2 extends Observable {

    private String state;

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
        int j = countObservers();
        System.out.println("2"+j);
        setChanged();
        //一般是在这里增加订阅
        addObserver(new JavaSubject());
        addObserver(new JavaSubject2());
        int i = countObservers();
        System.out.println("2"+i);
        notifyObservers();
    }
}

package com.boot.lijunhao.guanchazhemoshi;

import java.util.*;
import java.util.Observer;

/**
 * Created by lijunhao on 2017/8/31.
 */
public class JavaSubject implements Observer {

    //无参构造
    public JavaSubject() {
    }

    //方便添加addObserver
    public JavaSubject(JavaObserver javaObserver) {
        javaObserver.addObserver(this);
    }
    //方便添加addObserver
    public JavaSubject(JavaObserver2 javaObserver) {
        javaObserver.addObserver(this);
    }

    //update方法每次修改( setChanged 和notifyObservers)就会自动调用的
    @Override
    public void update(Observable o, Object arg) {
        if(o instanceof JavaObserver){
            JavaObserver javaObserver =  (JavaObserver)o;
            System.out.println(javaObserver.getState());
        }else{
            JavaObserver2 javaObserver =  (JavaObserver2)o;
            System.out.println(javaObserver.getState());
        }
    }
}

package com.boot.lijunhao.guanchazhemoshi;

import java.util.Observable;
import java.util.Observer;

/**
 * 作用同JavaSubject
 * Created by lijunhao on 2017/8/31.
 */
public class JavaSubject2 implements Observer {

    //需要在
    public JavaSubject2() {
    }

    public JavaSubject2(JavaObserver javaObserver) {
        javaObserver.addObserver(this);
    }

    public JavaSubject2(JavaObserver2 javaObserver) {
        javaObserver.addObserver(this);
    }

    //update方法每次修改( setChanged 和notifyObservers)就会自动调用的
    @Override
    public void update(Observable o, Object arg) {
        if(o instanceof JavaObserver){
            JavaObserver javaObserver =  (JavaObserver)o;
            System.out.println(javaObserver.getState()+"dsssssssssgdfgdfgfjtrfsdcsadsdgfsdfsdsafsdfsdfdsfs");
        }else{
            JavaObserver2 javaObserver =  (JavaObserver2)o;
            System.out.println(javaObserver.getState()+"dsssssssssgdfgdfgfjtrfsdcsadsdgfsdfsdsafsdfsdfdsfs");
        }
    }
}

package com.boot.lijunhao.guanchazhemoshi;

/**
 * Created by lijunhao on 2017/8/31.
 */
public class JavaStart {

    public static void main(String[] args) {
        JavaObserver javaObserver = new JavaObserver();
        JavaObserver2 javaObserver2 = new JavaObserver2();
        //在这里增加订阅类
        new JavaSubject(javaObserver);
        new JavaSubject(javaObserver2);
        new JavaSubject2(javaObserver2);
        javaObserver.setState("fdddddddddddddddddd");
        javaObserver.setState("dfdgdfgfgdf");
        javaObserver2.setState("ddddddddddddddddddddddddddddddddddddddddddddddddd");
    }
}

  • 3.3,结果
11
11
fdddddddddddddddddd
11
11
dfdgdfgfgdf
22
24
ddddddddddddddddddddddddddddddddddddddddddddddddddsssssssssgdfgdfgfjtrfsdcsadsdgfsdfsdsafsdfsdfdsfs
ddddddddddddddddddddddddddddddddddddddddddddddddd
ddddddddddddddddddddddddddddddddddddddddddddddddddsssssssssgdfgdfgfjtrfsdcsadsdgfsdfsdsafsdfsdfdsfs
ddddddddddddddddddddddddddddddddddddddddddddddddd

© 著作权归作者所有

共有 人打赏支持
月夜筱风
粉丝 0
博文 55
码字总数 19574
作品 0
闵行
程序员
私信 提问
JavaScript常用设计模式

设计模式 设计模式是一种在长时间的经验与错误中总结出来可服用的解决方案。 设计模式主要分为3类: 创建型设计模式:专注于处理对象的创建 Constructor构造器模式,Factory工厂模式,Singl...

a独家记忆
07/13
0
0
观察者模式 vs 发布-订阅模式

我曾经在面试中被问道,“观察者模式和发布订阅模式的有什么区别?” 我迅速回忆起“Head First设计模式”那本书: 发布 + 订阅 = 观察者模式 “我知道了,我知道了,别想骗我” 我微笑着回答...

缪宇
06/29
0
0
JavaScript 中常见设计模式整理

开发中,我们或多或少地接触了设计模式,但是很多时候不知道自己使用了哪种设计模式或者说该使用何种设计模式。本文意在梳理常见设计模式的特点,从而对它们有比较清晰的认知。 JavaScript 中...

牧云云
05/18
0
0
每天一个设计模式之订阅-发布模式

博主按:《每天一个设计模式》旨在初步领会设计模式的精髓,目前采用(靠这吃饭)和(纯粹喜欢)两种语言实现。诚然,每种设计模式都有多种实现方式,但此小册只记录最直截了当的实现方式 :)...

godbmw
12/10
0
0
JavaScript设计模式之观察者模式

前言 准备研究一下MVVM的一些东西,由于MVVM运用了观察者模式的思想,因此翻开了《JavaScript设计模式与开发实践》一书,将观察者模式学习了一遍,顺便有对一些常用的设计模式进行一些了解,...

Srtian
05/22
0
0

没有更多内容

加载失败,请刷新页面

加载更多

使用正则表达式实现网页爬虫的思路详解

网页爬虫:就是一个程序用于在互联网中获取指定规则的数据。这篇文章主要介绍了使用正则表达式实现网页爬虫的思路详解,需要的朋友可以参考下 网页爬虫:就是一个程序用于在互联网中获取指定规...

前端小攻略
19分钟前
0
0
vue中锚点的三种方法

第一种: router.js中添加 mode: 'history', srcollBehavior(to,from,savedPosition){ if(to.hash){ return {selector:to.hash } } } 组件: <template><div><ul class="li......

peakedness丶
20分钟前
0
0
记一次面试最常见的10个Redis"刁难"问题

导读:在程序员面试过程中Redis相关的知识是常被问到的话题。作为一名在互联网技术行业打击过成百上千名的资深技术面试官,本文作者总结了面试过程中经常问到的问题。十分值得一读。 Redis在...

小刀爱编程
今天
20
0
TiDB Lab 诞生记 | TiDB Hackathon 优秀项目分享

本文由红凤凰粉凤凰粉红凤凰队的成员主笔,他们的项目 TiDB Lab 在本届 TiDB Hackathon 2018 中获得了二等奖。TiDB Lab 为 TiDB 培训体系增加了一个可以动态观测 TiDB / TiKV / PD 细节的动画...

TiDB
今天
5
0
当区块链遇到零知识证明

本文由云+社区发表 当区块链遇到零知识证明 什么是零知识证明 零知识证明的官方定义是能够在不向验证者任何有用的信息的情况下,使验证者相信某个论断是正确的。这个定义有点抽象,下面笔者举...

腾讯云加社区
今天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部