观察者模式 详解 设计模式

本文详细介绍了观察者模式,包括其定义、结构(抽象主题、具体主题和观察者),以及如何通过解耦实现对象间的通信。同时讨论了模式的优点(降低耦合、广播机制)和可能的缺点(观察者数量大、循环依赖问题)。
摘要由CSDN通过智能技术生成

观察者模式

观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,使得当一个对象的状态发生变化时,其相关依赖对象都会得到通知并自动更新,如同发布-订阅模式。常见的情况如:公众号更新内容,所有的关注用户都能自动收到信息。

结构:

  • 抽象主题(Subject):也称为被观察者,把所有观察者对象保存在一个集合里。主题可以提供接口去添加、删除和通知观察者的方法。
  • 抽象观察者(Observer):抽象观察者是接收主题通知的对象。观察者需要实现一个更新方法,当收到主题的通知时,调用该方法进行更新操作。
  • 具体主题(Concrete Subject):具体主题是主题的具体实现类。该角色将有关状态存入具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知。
  • 具体观察者(Concrete Observer):具体观察者是抽象观察者的具体实现类。它实现了更新方法,定义了在收到主题通知时需要执行的具体操作。

观察者模式通过将主题和观察者解耦,实现了对象之间的松耦合。当主题的状态发生改变时,所有依赖于它的观察者都会收到通知并进行相应的更新。

图例:

请添加图片描述

代码案例:

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

// 主题接口(被观察者)
interface Subject {
    void registerObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers();
}

// 具体主题(具体的被观察者)
class ConcreteSubject implements Subject {  
    private List<Observer> observers = new ArrayList<>();
    private int state;

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
        notifyObservers();
    }

    @Override
    public void registerObserver(Observer observer) {
        observers.add(observer);
    }

    @Override
    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }

    @Override
    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update();
        }
    }
}

// 观察者接口
interface Observer {
    void update();
}

// 具体观察者
class ConcreteObserver implements Observer {
    private ConcreteSubject subject;

    public ConcreteObserver(ConcreteSubject subject) {
        this.subject = subject;
        this.subject.registerObserver(this);
    }

    @Override
    public void update() {
        System.out.println("State changed: " + subject.getState());
    }
}

// 使用示例
public class Main {
    public static void main(String[] args) {
        ConcreteSubject subject = new ConcreteSubject();
        ConcreteObserver observer1 = new ConcreteObserver(subject);
        ConcreteObserver observer2 = new ConcreteObserver(subject);

        // 改变主题状态
        subject.setState(10);
        subject.setState(20);
    }
}

在这个代码中,Subject 是主题接口,定义了注册、移除和通知观察者的方法。ConcreteSubject 是具体的主题类,维护了观察者列表,并在状态改变时通知观察者。Observer 是观察者接口,定义了观察者需要实现的更新方法。ConcreteObserver 是具体的观察者类,实现了更新方法,并在构造函数中注册到主题对象中。在 Main 类中,创建了主题对象和两个观察者对象,然后改变主题的状态,观察者对象会收到通知并更新。

使用场景

  • 对象间存在一对多关系,当一个对象的改变需要同时改变其他对象的时候。
  • 当一个抽象模型有两个方面,其中一个方面依赖于另一方面时。

优缺点

优点:

  • 降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。
  • 被观察者发送通知,所有注册的观察者都会收到信息【可以实现广播机制】

缺点:

  • 如果观察者非常多的话,那么所有的观察者收到被观察者发送的通知会耗时
  • 如果被观察者有循环依赖的话,那么被观察者发送通知会使观察者循环调用,会导致系统崩溃
  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值