0
点赞
收藏
分享

微信扫一扫

Java设计模式--观察者模式--使用/详解/实例

夕颜合欢落 2022-03-12 阅读 67

原文网址:

简介

说明

        本文用示例介绍观察者模式的用法。

观察者模式的含义

模式的角色

  1. 抽象被观察者角色(Subject)   //也就是一个抽象主题
    1. 它把所有观察者对象的引用保存在一个集合中,每个主题都可以有任意数量的观察者。
    2. 象主题提供一个接口,可以增加和删除观察者角色。
    3. 一般用一个抽象类和接口来实现。
  2. 抽象观察者角色(Observer)
    1. 为所有的具体观察者定义一个接口,在得到主题通知时更新自己。
  3. 具体被观察者角色(ConcernSubject)
    1. 也就是一个具体的主题,在集体主题的内部状态改变时,所有登记过的观察者发出通知。
  4. 具体观察者角色(ConcernObserver)
    1. 实现抽象观察者角色所需要的更新接口,使本身的状态与主题的状态相协调

实例

项目的所有文件

主题(公众号)

抽象主题(公众号)

package com.example.a.subject;

import com.example.a.observer.Observer;

/**
 * 抽象被观察者(主题): 公众号
 */
public interface OfficialAccount {
    /**
     * 关注
     * @param observer 用户
     */
    void follow(Observer observer);

    /**
     * 取消关注
     * @param observer 用户
     */
    void unfollow(Observer observer);

    /**
     * 公众号通知
     * @param message 通知的内容
     */
    void notify(String message);
}

具体主题(某个公众号) 

package com.example.a.subject;

import com.example.a.observer.Observer;

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

/**
 * 具体被观察者(主题): Knife公众号
 */
public class KnifeOfficialAccount implements OfficialAccount {
    private List<Observer> list;

    public KnifeOfficialAccount() {
        this.list = new ArrayList<>();
    }

    @Override
    public void follow(Observer observer) {
        list.add(observer);
    }

    @Override
    public void unfollow(Observer observer) {
        list.remove(observer);
    }

    @Override
    public void notify(String message) {
        System.out.println("Knife公众号发了新消息:" + message);
        for (Observer observer : list) {
            observer.operate(message);
        }
    }

    public List<Observer> getList() {
        return list;
    }

    public void setList(List<Observer> list) {
        this.list = list;
    }
}

观察者(用户)

抽象观察者(用户)

package com.example.a.observer;

/**
 * 抽象观察者: 用户
 */
 public interface Observer {
    /**
     * 用户收到通知后的操作
     */
    void operate(String message);
}

具体观察者(某个用户) 

package com.example.a.observer;

/**
 * 具体观察者: 用户
 */
public class UserObserver implements Observer {

    private String userName;

    public UserObserver(String userName) {
        this.userName = userName;
    }

    @Override
    public void operate(String message) {
        System.out.println("用户【" + this.userName + "】接收新消息:" + message);
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }
}

测试

测试类

package com.example.a;

import com.example.a.observer.Observer;
import com.example.a.observer.UserObserver;
import com.example.a.subject.KnifeOfficialAccount;
import com.example.a.subject.OfficialAccount;

public class Demo {
    public static void main(String[] args) {
        Observer user1 = new UserObserver("张三");
        Observer user2 = new UserObserver("李四");
        Observer user3 = new UserObserver("王五");

        OfficialAccount officialAccount = new KnifeOfficialAccount();

        officialAccount.follow(user1);
        officialAccount.follow(user2);
        officialAccount.follow(user3);

        officialAccount.notify("本文介绍常见的Java面试题");

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

        officialAccount.unfollow(user2);
        System.out.println("李四取消了订阅");

        System.out.println("=================================================");
        officialAccount.notify("本文介绍察者设计模式");
    }
}

结果

Knife公众号发了新消息:本文介绍常见的Java面试题
用户【张三】接收新消息:本文介绍常见的Java面试题
用户【李四】接收新消息:本文介绍常见的Java面试题
用户【王五】接收新消息:本文介绍常见的Java面试题
=================================================
李四取消了订阅
=================================================
Knife公众号发了新消息:本文介绍察者设计模式
用户【张三】接收新消息:本文介绍察者设计模式
用户【王五】接收新消息:本文介绍察者设计模式

SpringBoot的观察者模式

        实际上,我们可以直接使用Spring的事件监听机制,它就是观察者模式,用起来更方便。见:SpringBoot--事件监听机制--使用/实例/原理_IT利刃出鞘的博客-CSDN博客

JDK的观察者模式

简介

        在 Java 中,通过 java.util.Observable 类和 java.util.Observer 接口定义了观察者模式,只要实现它们的子类就可以编写观察者模式实例。

1. Observable

        Observable 类是抽象目标类(被观察者),它有一个 Vector 集合成员变量,用于保存所有要通知的观察者对象,下面来介绍它最重要的 3 个方法。

  1. void addObserver(Observer o) 方法:用于将新的观察者对象添加到集合中。
  2. void notifyObservers(Object arg) 方法:调用集合中的所有观察者对象的 update方法,通知它们数据发生改变。通常越晚加入集合的观察者越先得到通知。
  3. void setChange() 方法:用来设置一个 boolean 类型的内部标志,注明目标对象发生了变化。当它为true时,notifyObservers() 才会通知观察者。

2. Observer

        Observer 接口是抽象观察者,它监视目标对象的变化,当目标对象发生变化时,观察者得到通知,并调用 update 方法,进行相应的工作。

示例

警察抓小偷也可以使用观察者模式来实现,警察是观察者,小偷是被观察者。

小偷是一个被观察者,所以需要继承Observable类

package com.example.a;

import java.util.Observable;

public class Thief extends Observable {

    private String name;

    public Thief(String name) {
        this.name = name;
    }
    
    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void steal() {
        System.out.println("小偷-" + name + ":我偷东西了");
        super.setChanged(); //changed  = true
        super.notifyObservers();
    }
}

警察是一个观察者,所以需要实现Observer接口 

package com.example.a;

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

public class Policemen implements Observer {

    private String name;

    public Policemen(String name) {
        this.name = name;
    }
    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    @Override
    public void update(Observable observable, Object arg) {
        System.out.println("警察-" + name + ": "
                + ((Thief) observable).getName()
                + ",我已经盯你很久了,终于抓到你了");
    }
}

测试

package com.example.a;

public class Demo {
    public static void main(String[] args) {
        //创建小偷对象
        Thief t = new Thief("老王");

        //创建警察对象
        Policemen p = new Policemen("小李");

        //让警察盯着小偷
        t.addObserver(p);

        //小偷偷东西
        t.steal();
    }
}

结果

小偷-老王:我偷东西了
警察-小李: 老王,我已经盯你很久了,终于抓到你了

其他网址

Java设计模式之观察者模式_贺兰山的那个脉的博客-CSDN博客

设计模式-观察者模式_逍遥壮士-CSDN博客

举报

相关推荐

0 条评论