揭开观察者模式的面纱

定义

观察者模式是这样定义的:在对象之间存在一对多的依赖关系,当主对象的状态发生改变的时候,依赖它的全部从对象都能接收到改变的信息并作出相应的处理。好比老师和学生,微信公众号和订阅的用户,消息队列的生产者和消费者。观察者模式的实质就是发布订阅模式,发布者发布消息,订阅者获取消息,订阅了就能收到消息,没订阅就收不到消息。bash

UML

观察者模式有四个角色:
一、抽象被观察者:也就是一个抽象的主题,它将全部观察者放到一个集合(队列)中,这个主题定义了添加观察者、一处观察者,以及通知观察者等方法。
二、抽象观察者:为具体的观察者定义了一个接口
三、具体被观察者:对应一个具体的主题,在自身主题的内部发生变化时,通知集合中的全部观察者
四、具体观察者:依赖具体的被观察者,对应它的主题,实现接收通知的接口。微信

具体实现

你们都熟悉这么一个场景,咱们订阅了不少了微信公众号,这些微信公众号后台都有管理员在运营,当他们在后台发布了一篇推文,咱们这些订阅了的用户均可以收到这篇推文,微信公众号就是被观察者,订阅的用户就是观察者。ide

1.定义抽象被观察者接口

/**
 * 抽象被观察者接口,定义添加,移除和通知观察者的接口
 */
public interface Observable {

    public void registerObserver(Observer observer);

    public void removeObserver(Observer observer);

    public void notifyObserver();

}
复制代码

2.定义抽象观察者接口

/**
 * 抽象观察者接口,定义接收通知方法
 */
public interface Observer {

    public void updateMessage(String message);
}
复制代码

3.定义具体被观察者类,表示一个特定主题(微信公众号),包含一个List集合,存储与之关联的观察者,对其进行管理(添加,移除和发送通知)

/**
 * 被观察者,微信公众号/服务号/订阅号
 * 实现了Observable,实现添加订阅者,删除订阅者,通知订阅者的基本功能
 */
public class WechatServer implements Observable{

    private List<Observer> observers;

    private String message;

    public WechatServer() {
        observers = new ArrayList<>();
    }


    @Override
    public void registerObserver(Observer observer) {
        if (observers == null) {
            observers = new ArrayList<>();
        }
        observers.add(observer);
    }

    @Override
    public void removeObserver(Observer observer) {
        if (observers == null || observers.isEmpty()) {
            return;
        }
        observers.remove(observer);
    }

    @Override
    public void notifyObserver() {
        if (observers == null) {
            return;
        }
        for (Observer observer : observers) {
            observer.updateMessage(message);
        }
    }

    public void publicMessage(String message) {
        if (StringUtils.isBlank(message)) {
            throw new IllegalArgumentException("不能发布空消息");
        }
        this.message = message;
        System.out.println("微信公众号管理员发布信息:"+message);
        //通知全部订阅者
        notifyObserver();
    }
}
复制代码

4.定义具体观察者类,依赖微信公众号这一主题的就是订阅用户

public class WechatUser implements Observer{

    private String name;

    private String message;

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

    @Override
    public void updateMessage(String message) {
        this.message = message;
        System.out.println(name+"收到推送消息:"+message);
    }
    
}
复制代码

5.测试用例

public static void main(String [] args) {
        //定义微信公众号
        WechatServer server = new WechatServer();

        //定义三个订阅的用户
        WechatUser user1 = new WechatUser("乔峰");
        WechatUser user2 = new WechatUser("令狐冲");
        WechatUser user3 = new WechatUser("杨过");

        //三人订阅了公众号
        server.registerObserver(user1);
        server.registerObserver(user2);
        server.registerObserver(user3);

        //微信公众号发布消息
        server.publicMessage("JAVA是最流行的语言!!");

        //乔峰取消了订阅
        server.removeObserver(user1);
        //微信公众号再次发布消息(取消订阅的用户郑光宇就收不到消息了)
        server.publicMessage("JAVA是最好用的语言!!");

    }
复制代码

运行结果:测试

相关文章
相关标签/搜索