JAVA设计模式18:观察者模式,建立了一对多的依赖关系

2023-11-03 09:41:12 浏览数 (1)

作者主页:Designer 小郑 作者简介:3年JAVA全栈开发经验,专注JAVA技术、系统定制、远程指导,致力于企业数字化转型,CSDN博客专家,阿里云社区专家博主,蓝桥云课讲师。



一、什么是观察者模式

观察者模式(Observer Pattern)是一种行为型设计模式,它建立了一种一对多的依赖关系,让多个观察者对象同时监听一个被观察者对象的状态变化,当被观察者对象的状态发生变化时,会自动通知所有观察者对象进行相应的更新操作。

观察者模式也被称为发布-订阅(Publish-Subscribe)模式。

在观察者模式中,有

4

个核心角色。

  1. Subject(被观察者):它是一个抽象类或接口,定义了被观察者对象的基本操作,包括添加、删除和通知观察者的方法。
  2. ConcreteSubject(具体被观察者):它是被观察者的具体实现,维护被观察者的状态,并在状态发生变化时通知所有观察者。
  3. Observer(观察者):它是一个抽象类或接口,定义了观察者对象的基本操作,包括更新方法。
  4. ConcreteObserver(具体观察者):它是观察者的具体实现,实现了观察者的更新方法,以便在接收到被观察者的通知时进行相应的操作。

观察者模式的核心思想是将观察者和被观察者解耦,使它们之间的依赖关系松散,从而实现对象间的松耦合。观察者模式能够在不改变被观察者和观察者之间的代码的情况下,动态地添加和删除观察者,从而提高了系统的灵活性和可扩展性。它常被用于事件处理、消息推送、GUI编程等场景。


二、观察者模式实例

下面是一个简单的 Java 代码示例,演示了观察者模式的实现,请同学们复制到本地执行。

代码语言:javascript复制
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 String message;
    
    @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(message);
        }
    }
    
    public void setMessage(String message) {
        this.message = message;
        notifyObservers();
    }
}

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

// 具体的观察者
class ConcreteObserver implements Observer {
    private String name;
    
    public ConcreteObserver(String name) {
        this.name = name;
    }
    
    @Override
    public void update(String message) {
        System.out.println(name   " 收到消息:"   message);
    }
}

public class ObserverPatternDemo {
    public static void main(String[] args) {
        ConcreteSubject subject = new ConcreteSubject();
        
        ConcreteObserver observer1 = new ConcreteObserver("观察者1");
        ConcreteObserver observer2 = new ConcreteObserver("观察者2");
        
        subject.registerObserver(observer1);
        subject.registerObserver(observer2);
        
        subject.setMessage("Hello World!");
        
        subject.removeObserver(observer1);
        
        subject.setMessage("How are you?");
    }
}

在上述示例中,ConcreteSubject 是具体的被观察者,实现了 Subject 接口,它维护了一个观察者列表,并实现了注册、删除和通知观察者的方法。

ConcreteObserver 是具体的观察者,实现了 Observer 接口。它定义了更新方法,当收到被观察者的通知时,会执行相应的操作。

ObserverPatternDemo 类中,我们创建了一个具体的被观察者对象 subject,以及两个具体的观察者对象 observer1observer2。我们通过调用 registerObserver 方法将观察者添加到被观察者的列表中。然后,我们调用 setMessage 方法来设置被观察者的消息,从而触发通知操作。

最后,我们通过调用 removeObserver 方法将一个观察者从被观察者的列表中移除,再次调用 setMessage 方法来触发通知操作。运行代码,可以看到观察者收到了相应的消息。


三、观察者模式的应用场景

观察者模式在许多应用程序中都有广泛的应用,以下是观察者模式常见的应用场景,请同学们认真学习。

  1. GUI编程:在图形用户界面中,常常使用观察者模式来监听用户界面的交互事件,例如按钮的点击、菜单的选择等。当事件发生时,观察者会被通知并执行相应的操作,从而实现用户界面和业务逻辑的解耦。
  2. 消息推送系统:观察者模式常被用于实现消息推送系统。当有新消息产生时,被观察者会通知所有的观察者,以便它们能够及时接收到新消息并进行相应的处理。
  3. 订阅-发布模式:订阅-发布模式是观察者模式的一种扩展,常用于事件驱动的系统中。订阅者通过订阅感兴趣的事件,当事件发生时,发布者会通知所有订阅者,使它们能够响应相应的事件。
  4. 数据库触发器:当数据库中的数据发生改变时,触发器可以通知相关的观察者进行相应的操作。观察者可以是其他数据库,或者是应用程序中的其他模块,以实现数据的同步和一致性。
  5. 股票交易系统:在股票交易系统中,经纪人和投资者之间的关系可以使用观察者模式来建模。当股票价格发生变化时,经纪人会通知所有的投资者,以便他们能够及时作出相应的决策。

观察者模式适用于当一个对象的改变需要通知其他多个对象时,同时观察者对象之间应尽量保持独立,以减少耦合性。


四、观察者模式面试题

  1. 什么是观察者模式?它解决了什么问题?
  2. 观察者模式的核心角色有哪些?
  3. 观察者模式和发布-订阅模式有何区别?
  4. 观察者模式如何实现对象之间的解耦?
  5. 观察者模式的优点是什么?
  6. 观察者模式的缺点是什么?
  7. 如何实现一个简单的观察者模式?
  8. 观察者模式在哪些场景下应用较为常见?
  9. 如何防止观察者模式中的内存泄漏问题?
  10. 观察者模式和回调函数有何异同?

0 人点赞