观察者模式


1. 类图

image.png

  • Subject:目标对象
    • 一个目标可以被多个观察者观察
    • 目标提供观察者订阅和取消的维护
    • 目标对象发生变化,通知所有有效观察者
  • Observer:定义观察者接口,提供目标对象变化时,对应观察者的更新方法
  • ConcreteObserver:具体观察者实现
  • ConcreteSubject:具体目标对象实现

2. 示例

修改目标的数据,触发相应通知,联动调用观察者的方法

2.1 目标对象

知道所有的观察者,并提供和维护观察者的订阅与退订逻辑

public class Subject {
    private List<Observer> readers = new ArrayList<>();

    // 订阅报纸
    public void subscribe(Observer reader){
        System.out.println(String.format("读者【%s】订阅了报纸", ((Reader) reader).getName()));
        readers.add(reader);
    }

    // 退订报纸
    public void unsubscribe(Observer reader){
        System.out.println(String.format("读者【%s】退订了报纸", ((Reader) reader).getName()));
        readers.remove(reader);
    }

    // 向所有读者推送报纸内容
    public void notifyAllReader(){
        readers.forEach(reader -> reader.read(this));
    }
}

2.2 具体的目标对象

着重描述通知的内容

public class Newspaper extends Subject {
    // 报纸内容
    private String content;

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        // 报纸内容更新
        this.content = content;
        // 向所有读者推送报纸内容
        notifyAllReader();
    }
}

2.3 观察者

public interface Observer {
    // 报纸阅读
    void read(Subject subject);
}

2.4 具体的观察者

public class Reader implements Observer {
    private String name;
    public Reader() {}
    public Reader(String name) {this.name = name;}

    public String getName() {
        return name;
    }

    @Override
    public void read(Subject subject) {
        System.out.println(String.format("读者%s正在阅读最新一期的报纸,报纸主题为:%s",
                name, ((Newspaper) subject).getContent()));
    }
}

2.5 客户端

public class Client {
    public static void main(String[] args) {
        // 初始化读者
        Observer reader1 = new Reader("张三");
        Observer reader2 = new Reader("李四");

        // 报纸订阅
        Newspaper subject = new Newspaper();
        subject.subscribe(reader1);
        subject.subscribe(reader2);

        // 报纸更新
        subject.setContent("如何使用观察者模式");

        // 退订
        subject.unsubscribe(reader1);

        // 报纸更新
        subject.setContent("如何更好的使用观察者模式");
    }
}

3. 优点

  • 实现了观察者与目标之间的抽象耦合
  • 目标对象与观察者之间可以动态联动

4. 缺点

  • 目标对象发生变化时,都会触发观察者的update方法,无论观察者是否需要
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值