Skip to content
CodingDiary
返回

设计模式之行为型设计模式-观察者模式

编辑页面
导读

微信朋友圈点赞,为什么所有好友都能收到通知?因为观察者模式!本文用「私信推送通知」的场景讲解:Pusher 作为被观察者发布消息,User 作为观察者订阅并接收。setChanged() + notifyObservers() 触发通知。JDK Observer、Guava EventBus、Spring ApplicationEvent 都是典型应用。

1. 模式简介

定义了对象之间的一对多依赖,让多个观察者对象同时监听一个主体对象,当主体对象发生变化时,它的所有观察者对象都会收到通知并更新。属于行为型设计模式。观察者模式也被叫做发布订阅模式

2. 示例代码

这里我们使用观察者模式来模拟一个消息推送通知的场景。

/**
 * <p>
 * 消息
 * </p>
 *
 * @author yangkai.shen
 * @date Created in 2019/11/24 17:36
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Message {
    private String message;
    private String from;
    private String to;
}
/**
 * <p>
 * 消息推送,被观察者
 * </p>
 *
 * @author yangkai.shen
 * @date Created in 2019/11/24 17:36
 */
public class Pusher extends Observable {
    private static Pusher PUSHER = null;

    private Pusher() {
    }

    public static Pusher getInstance() {
        if (null == PUSHER) {
            PUSHER = new Pusher();
        }
        return PUSHER;
    }

    /**
     * 推送消息
     *
     * @param message 消息
     */
    public void pushMessage(Message message) {
        System.out.println(message.getFrom() + "" + message.getTo() + " 发送了一条私信~~");
        // 触发状态变化
        setChanged();
        // 提醒观察者
        notifyObservers(message);
    }
}
/**
 * <p>
 * 用户,观察者
 * </p>
 *
 * @author yangkai.shen
 * @date Created in 2019/11/24 17:43
 */
@Data
@AllArgsConstructor
public class User implements Observer {
    private String name;

    /**
     * 被观察对象改变的时候,会触发这个方法
     *
     * @param o   the observable object.
     * @param arg an argument passed to the <code>notifyObservers</code>
     */
    @Override
    public void update(Observable o, Object arg) {
        Message message = (Message) arg;

        if (this.getName().equals(message.getTo())) {
            System.err.println(name + ",你收到一条来自 " + message.getFrom() + " 的私信!");
            System.err.println("私信内容: " + message.getMessage());
        }

    }
}
/**
 * <p>
 * 观察者模式,测试类
 * </p>
 *
 * @author yangkai.shen
 * @date Created in 2019/11/24 17:52
 */
public class PatternTest {
    public static void main(String[] args) {
        User xkcoding = new User("xkcoding");
        Pusher pusher = Pusher.getInstance();
        Message message = new Message("你好", "user-1", "xkcoding");
        pusher.addObserver(xkcoding);
        pusher.pushMessage(message);
    }
}
user-1 xkcoding 发送了一条私信~~
xkcoding,你收到一条来自 user-1 的私信!
私信内容: 你好

3. UML 图例

design-pattern-observer-uml

4. 应用

// 1. JDK java.util.Observer 、 java.util.Observable
// 2. Guava EventBus
// 3. Spring ApplicationEvent
// 4. Android ClickListerner...

// 生活中
// 1. 微信朋友圈通知
// 2. 网站私信通知

5. 场景

观察者模式主要用于在关联行为之间建立一套触发机制的场景。

6. 优缺点

优点: 1、观察者和被观察者之间建立了一个抽象的耦合。 2、观察者模式支持广播通信。

缺点: 1、观察者之间有过多的细节依赖、提高时间消耗及程序的复杂度。2、使用需要及其谨慎,要避免循环调用。

7. 完整代码地址

https://github.com/xkcoding/design-pattern/tree/master/src/main/java/com/xkcoding/design/pattern/behavioral/observer


编辑页面
分享到:

上一篇
设计模式之结构型设计模式-装饰者模式
下一篇
设计模式之行为型设计模式-模板方法模式