设计模式-观察者模式

发布时间:2023年12月18日
设计模式专栏


模式介绍

观察者模式是一种对象行为模式,它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

在观察者模式中,主题是通知的发布者,它发出通知时并不需要知道谁是它的观察者,可以有任意数目的观察者订阅并接收通知。这种模式被广泛应用于软件界面元素之间的交互,在业务对象之间的交互、权限管理等方面也有广泛的应用。

例如,用户界面可以作为一个观察者,业务数据是被观察者,用户界面观察业务数据的变化,发现数据变化后,就显示在界面上。这种模式不仅将观察者和被观察的对象分离开,还划定了清晰的界限,提高了应用程序的可维护性和重用性。

在这里插入图片描述

模式特点

观察者模式的优点主要包括:

  1. 解耦:观察者模式降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。目标只需要知道观察者接口,不需要知道具体的观察者是谁。
  2. 广播通信:主题会向所有的观察者发出通知,实现了“广播通信”。
  3. 符合开闭原则:观察者模式符合“开闭原则”的要求。

观察者模式的缺点主要包括:

  1. 可能存在循环依赖:在观察者和观察目标之间可能存在循环依赖,这可能导致系统崩溃。
  2. 通知发布效率:如果一个被观察者对象有很多的直接和间接的观察者,将所有的观察者都通知到会花费很多时间,影响程序的效率。
  3. 缺乏变化原因的反馈:观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

在这里插入图片描述

应用场景

观察者模式的应用场景主要包括:

  1. 事件管理系统:在事件管理系统中,可以使用观察者模式来管理事件的订阅和通知。当事件发生时,所有订阅了该事件的观察者都会收到通知。
  2. 新闻发布系统:在新闻发布系统中,可以使用观察者模式来管理新闻的订阅和推送。当有新的新闻发布时,所有订阅了该新闻的观察者都会收到通知。
  3. 实时通信系统:在实时通信系统中,可以使用观察者模式来管理用户之间的通信。当有新的消息或事件发生时,所有订阅了该用户或事件的观察者都会收到通知。
  4. 在线游戏:在线游戏中,观察者模式可以用于实现玩家的状态更新、技能冷却时间等提醒功能。

观察者模式适用于多个对象之间存在一对多依赖关系的场景,如消息订阅、事件处理、状态更新等。

在这里插入图片描述

观察者模式和责任链模式区别

观察者模式和责任链模式都是常用的设计模式,它们都可以用于解决对象之间的耦合问题,但它们的应用场景和实现方式有所不同。

  • 观察者模式是一种对象行为型模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,当主题对象发生变化时,它会自动通知所有的观察者对象,使它们能够及时更新自己的状态。这种模式的优点是能够实现对象之间的松耦合,主题对象和观察者对象之间不需要直接相互通信,而是通过中介者来进行通信,从而提高了系统的可扩展性和可维护性。

  • 责任链模式是一种行为型模式,它将多个对象组成一条链,每个对象都有机会处理请求。责任链模式的核心思想是将多个处理对象组成一条链,每个处理对象都有自己的处理方法,当一个请求到来时,它会依次经过链中的每个处理对象,直到有一个对象处理它为止。责任链模式的优点是能够动态地组合处理对象,增强系统的灵活性和可扩展性。

总的来说,观察者模式和责任链模式都是非常有用的设计模式,它们都能够解决对象之间的耦合问题,但它们的实现方式和应用场景有所不同。观察者模式适用于当一个对象的改变需要同时改变其他对象的时候,而责任链模式适用于当一个请求需要经过多个处理对象进行处理的时候。

在这里插入图片描述

代码示例

Java实现观察者模式

下面是一个简单的Java实现观察者模式的示例:

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

// 主题接口
interface Subject {
    void addObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers();
}

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

    public ConcreteSubject() {
        this.state = 0;
    }

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

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

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

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

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

// 具体观察者类
class ConcreteObserver implements Observer {
    private String name;

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

    @Override
    public void update(int state) {
        System.out.println(name + " received update with state: " + state);
    }
}

// 测试类
public class ObserverPatternDemo {
    public static void main(String[] args) {
        ConcreteSubject subject = new ConcreteSubject();
        Observer observer1 = new ConcreteObserver("Observer 1");
        Observer observer2 = new ConcreteObserver("Observer 2");
        subject.addObserver(observer1);
        subject.addObserver(observer2);
        subject.setState(10); // 更新状态,通知所有观察者
    }
}

在这个示例中,我们定义了一个Subject接口,它包含了添加、移除观察者和通知观察者的方法。然后我们创建了一个ConcreteSubject类,实现了Subject接口,并在其中维护了一个观察者列表。当状态发生变化时,我们调用notifyObservers方法,通知所有观察者更新。观察者接口Observer定义了观察者需要实现的方法update,具体观察者类ConcreteObserver实现了这个方法,并在其中打印接收到的状态。在测试类中,我们创建了一个主题对象和两个观察者对象,并将观察者对象添加到主题对象中。然后我们调用主题对象的setState方法来更新状态,并通知所有观察者更新。

python实现观察者模式

以下是一个简单的Python实现观察者模式的示例:

class Subject:
    def __init__(self):
        self._observers = []
        
    def attach(self, observer):
        self._observers.append(observer)
        
    def detach(self, observer):
        self._observers.remove(observer)
        
    def notify(self, value=None):
        for observer in self._observers:
            observer.update(value)
            
class Observer:
    def update(self, value):
        pass
    
class ConcreteObserver1(Observer):
    def update(self, value):
        print("ConcreteObserver1 received update with value:", value)
        
class ConcreteObserver2(Observer):
    def update(self, value):
        print("ConcreteObserver2 received update with value:", value)
        
if __name__ == "__main__":
    subject = Subject()
    observer1 = ConcreteObserver1()
    observer2 = ConcreteObserver2()
    subject.attach(observer1)
    subject.attach(observer2)
    subject.notify(100) # 输出:ConcreteObserver1 received update with value: 100 和 ConcreteObserver2 received update with value: 100
    subject.detach(observer1)
    subject.notify(200) # 输出:ConcreteObserver2 received update with value: 200

在这个示例中,我们定义了一个Subject类,它维护了一个观察者列表,并提供了添加、移除和通知观察者的方法。具体观察者类ConcreteObserver继承自Observer基类,并实现了update方法。在测试代码中,我们创建了一个主题对象和两个具体观察者对象,并将观察者对象添加到主题对象中。然后我们调用主题对象的notify方法来通知所有观察者更新,并在控制台输出每个观察者收到的值。接着我们移除其中一个观察者,再次调用notify方法来通知剩余的观察者更新,并在控制台输出每个观察者收到的值。
在这里插入图片描述

观察者模式在spring中的应用

观察者模式是一种设计模式,用于在对象之间建立一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。Spring框架中使用了观察者模式来支持事件处理和通知机制。

在Spring中,观察者模式主要应用在以下几个方面:

  1. 事件处理:Spring框架提供了事件处理机制,用于处理系统中的各种事件,比如用户登录、订单提交等。这些事件可以由应用程序中的任何组件发布,而观察者则可以订阅这些事件,并在事件发生时执行相应的操作。
  2. 通知机制:Spring框架提供了通知机制,用于在应用程序中的特定情况下发送通知。比如,当某个业务操作成功或失败时,可以发送相应的通知给相关人员。观察者可以在接收到通知后执行相应的操作,比如发送邮件、记录日志等。
  3. 依赖注入:Spring框架通过依赖注入的方式,将各个组件之间解耦,降低了代码的耦合度。观察者模式在这种场景下也可以发挥作用。比如,当某个组件的状态发生改变时,可以通知其他依赖该组件的组件,让它们更新自己的状态。

观察者模式在Spring框架中得到了广泛应用,它可以帮助我们实现松耦合、高可扩展性的应用程序。

在这里插入图片描述

文章来源:https://blog.csdn.net/zhangzehai2234/article/details/135006765
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。