观察者模式简介

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

在观察者模式中有如下角色:

==Subject==:抽象主题(抽象被观察者)

接口实现,规定了增加订阅者、删除订阅者、发布主题的基本方法。

==ConcreteSubject==:具体主题(具体被观察者)

抽象主题接口的实现类,该类保存具体的订阅者(观察者)对象,当发布主题时通知订阅者去更新。

==Observer==:抽象观察者

接口实现,规定了订阅主题,取消订阅、更新主题的基本方法

==ConcrereObserver==:具体观察者

抽象观察者的实现类,当收到主题的通知时更新以获取到主题。

观察者模式的简单实现

我们以微信公众号为例,假设微信用户是观察者,微信公众号是被观察者,有多个用户关注了人社系统这个公众号,当这个公众号发布消息时就会通知这些订阅的微信用户。

抽象观察者(Observer)

提供了订阅主题、取消订阅、更新主题这三个方法

package com.example;

/**
 * @Author: miansen
 * @Date: 2019/6/18 22:43
 */
public interface ObServer {

    /**
     * 订阅主题
     * @param subject
     */
    void subscribe(Subject subject);

    /**
     * 取消订阅
     * @param subject
     */
    void unsubscribe(Subject subject);

    /**
     * 更新主题
     * @param content:主题内容
     */
    void update(String content);
}

抽象被观察者(Subject)

提供了增加订阅者、删除订阅者、发布主题这三个方法

package com.example;

/**
 * @Author: miansen
 * @Date: 2019/6/18 22:41
 */
public interface Subject {

    /**
     * 增加订阅者
     * @param obServer
     */
    void attach(ObServer obServer);

    /**
     * 删除订阅者
     * @param obServer
     */
    void detach(ObServer obServer);

    /**
     * 发布主题
     * @param content:主题内容
     */
    void publish(String content);
}

具体观察者(ConcrereObserver)

package com.example;

/**
 * @Author: miansen
 * @Date: 2019/6/18 22:59
 */
public class WeChatUserObserver implements ObServer{

    /**
     * 微信用户名
     */
    private String name;

    public WeChatUserObserver(String name) {
        this.name = name;
    }

    @Override
    public void subscribe(Subject subject) {
        subject.attach(this);
    }

    @Override
    public void unsubscribe(Subject subject) {
        subject.detach(this );
    }

    @Override
    public void update(String content) {
        System.out.println(this.name + ",您订阅的内容:" + content);
    }
}

具体被观察者(ConcreteSubject)

package com.example;

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

/**
 * @Author: miansen
 * @Date: 2019/6/18 22:49
 */
public class SubscriptionSubject implements Subject{

    /**
     * 用于存储订阅微信公众号的用户
     */
    private List<ObServer> obServers = new ArrayList<>();

    @Override
    public void attach(ObServer obServer) {
        obServers.add(obServer);
    }

    @Override
    public void detach(ObServer obServer) {
        obServers.remove(obServer);
    }

    @Override
    public void publish(String content) {
        obServers.forEach(obServer -> obServer.update(content));
    }
}

客户端调用

package com.example;

/**
 * @Author: miansen
 * @Date: 2019/6/18 23:06
 */
public class Client {

    public static void main(String[] agrs){
        // 创建微信公众号(被观察者)
        Subject subject = new SubscriptionSubject();

        // 创建微信用户(观察者)
        ObServer weChatUserObserver1 = new WeChatUserObserver("张三");
        ObServer weChatUserObserver2 = new WeChatUserObserver("李四");
        ObServer weChatUserObserver3 = new WeChatUserObserver("王五");

        // 订阅公众号
        weChatUserObserver1.subscribe(subject);
        weChatUserObserver2.subscribe(subject);
        weChatUserObserver3.subscribe(subject);

        // 发布内容
        subject.publish("市本级人社系统将于今晚0点停机升级。");

        // 取消订阅
        weChatUserObserver3.unsubscribe(subject);

        // 发布内容
        subject.publish("市本级人社系统升级完毕。");
    }
}

结果

张三,您订阅的内容:市本级人社系统将于今晚0点停机升级。

李四,您订阅的内容:市本级人社系统将于今晚0点停机升级。

王五,您订阅的内容:市本级人社系统将于今晚0点停机升级。

张三,您订阅的内容:市本级人社系统升级完毕。

李四,您订阅的内容:市本级人社系统升级完毕。

原文链接:https://miansen.wang/2019/06/18/1/