17、设计模式之观察者模式

定义

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

结构

  • 抽象主题(Subject)角色,把所有观察者对象保存到一个集合里,每个主题都可以有任意数量的观察者,抽象主题提供一个接口,可以增加和删除观察者对象。
  • 具体主题(ConcreteSubject)角色:该角色将有关状态存入具体观察者对象,再具体主题内部状态发生变化时,给所有注册过的观察者发送通知。
  • 抽象观察者(Observer)角色:是观察者的抽象类,定义了一个更新接口,使得在得到主题的通知时更新自己。
  • 具体观察者(ConcreteObserver)角色:实现抽象观察者定义的接口,以便在得到通知时更新自己。

案例

模拟微信公众号给关注该公众号的用户推送更新内容。
在这里插入图片描述
抽象观察者

package com.hupp.observer;

/**
 * 抽象观察者
 */
public interface Observer {
    
    
    void update(String message);
}

具体观察者

package com.hupp.observer;

public class WeiXinUser implements Observer{
    
    
    private String name;

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

    @Override
    public void update(String message) {
    
    
        System.out.println(name+"-"+message);
    }
}

抽象主题类

package com.hupp.observer;

/**
 * 抽象主题
 */
public interface Subject {
    
    
    //添加订阅者
    void attach(Observer observer);

    //删除订阅者
    void detach(Observer observer);

    //通知订阅者更新消息
    void notify(String message);
}

具体主题

package com.hupp.observer;

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

/**
 * 具体主题(被观察者)
 */
public class SubscriptionSubject implements Subject {
    
    
    //定义观察者对象集合
    private List<Observer> userList = new ArrayList<>();

    @Override
    public void attach(Observer observer) {
    
    
        userList.add(observer);
    }

    @Override
    public void detach(Observer observer) {
    
    
        userList.remove(observer);
    }

    @Override
    public void notify(String message) {
    
    
        for (Observer observer : userList) {
    
    
            observer.update(message);
        }
    }
}

客户端

package com.hupp.observer;

public class Client {
    
    
    public static void main(String[] args) {
    
    
        //创建公众号对象
        SubscriptionSubject subject = new SubscriptionSubject();

        //订阅公众号
        subject.attach(new WeiXinUser("张三"));
        subject.attach(new WeiXinUser("李四"));
        subject.attach(new WeiXinUser("王五"));

        //公众号更新,发消息给观察者对象
        subject.notify("完美世界股票大涨了");
    }
}

在这里插入图片描述

优缺点

  • 优点

    • 降低了观察者和被观察者之间的耦合关系
    • 被观察者发送通知,所有观察者都会收到消息【可以实现广播】
  • 缺点

    • 如果观察者很多的话,会影响性能,比较耗时
    • 如果被观察者有循环依赖的话,那么观察者发送通知回事观察者循环调用,会导致系统崩溃。

Guess you like

Origin blog.csdn.net/hpp3501/article/details/111885404