设计模式(行为型模式)观察者模式

目录

一、简介

**观察者模式(Observer Pattern)**是一种行为设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生变化时,其所有依赖者(观察者)都会自动收到通知并进行更新。

在观察者模式中,存在两类角色:

  • 主题(Subject): 也称为被观察者或可观察对象,维护了一组观察者对象,并提供了添加、删除和通知观察者的方法。
  • 观察者(Observer): 也称为订阅者,定义了一个更新接口或抽象类,用于接收主题的通知并进行相应的处理。

主题维护了一个观察者列表,当其内部状态发生变化时,会通知所有注册的观察者对象,使它们能够根据主题状态的变化进行相应的更新或处理。

观察者模式将主题和观察者解耦,使得主题和观察者之间的依赖关系变得松散,同时也提高了系统的灵活性和可扩展性。这种模式常用于订阅/发布系统、事件驱动系统以及需要一对多依赖关系的场景中。

二、观察者模式

下面是一个稍微复杂一些的观察者模式的示例,多个不同的观察者监听某个事件,并根据事件执行不同的操作(发送短信、发送邮件等):

2.1、事件接口及其实现

java 复制代码
// 事件接口
public interface Event {
    String getEventData();
}

// 具体事件类
public class ConcreteEvent implements Event {
    private String eventData;

    public ConcreteEvent(String data) {
        this.eventData = data;
    }

    @Override
    public String getEventData() {
        return eventData;
    }
}

2.2、观察者接口及其实现

java 复制代码
// 观察者接口
public interface Observer {
    void update(Event event);
}

// 具体观察者 -- 邮件
public class EmailObserver implements Observer {
    @Override
    public void update(Event event) {
        System.out.println("发送邮件: " + event.getEventData());
    }
}

// 具体观察者 -- 短信
public class SMSObserver implements Observer {
    @Override
    public void update(Event event) {
        System.out.println("发送短信: " + event.getEventData());
    }
}

2.3、主题接口及其实现

java 复制代码
// 主题接口
public interface Subject {
    void attach(Observer observer);
    void detach(Observer observer);
    void notifyObservers(Event event);
}

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

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

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

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

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

2.4、使用

java 复制代码
public class ObserverPatternExample {
    public static void main(String[] args) {
        ConcreteSubject subject = new ConcreteSubject();
		
        Observer smsObserver = new SMSObserver();
        Observer emailObserver = new EmailObserver();

        subject.attach(smsObserver);
        subject.attach(emailObserver);

        Event event = new ConcreteEvent("你正在登录账户,查看Alian的博客");
        subject.notifyObservers(event);
    }
}

运行结果:

复制代码
发送短信: 你正在登录账户,查看Alian的博客
发送邮件: 你正在登录账户,查看Alian的博客

三、优点与缺点

观察者模式具有以下优点和缺点:

优点

  • 解耦和灵活性: 主题和观察者之间的关系是松散耦合的,主题无需知道观察者的细节,使得系统更加灵活,能够方便地扩展和维护。
  • 一对多的依赖关系: 允许一个主题对象同时与多个观察者对象建立联系,当主题状态发生变化时,所有依赖于它的观察者都会得到通知。
  • 支持广播通信: 观察者模式支持广播通信机制,主题对象发出的通知会被所有相关的观察者接收。

缺点

  • 可能导致系统性能下降: 如果观察者过多或者操作复杂,通知所有观察者可能会影响性能。
  • 可能导致循环依赖: 观察者和主题之间的循环依赖可能会导致系统问题,需要小心设计以避免这种情况。
  • 可能引起内存泄漏: 如果观察者对象未被正确地移除,可能会导致内存泄漏问题。

总的来说,观察者模式是一种灵活、解耦的设计模式,能够实现对象间的一对多依赖关系。然而,在使用时需注意控制观察者数量、避免循环依赖和及时移除不需要的观察者,以确保系统的性能和稳定性。这个模式应用很广泛,比如springboot源码的事件发布机制。

相关推荐
半路下车34 分钟前
【Harmony OS 5】HarmonyOS应用测试指南
设计模式·harmonyos
周某某~41 分钟前
一.设计模式的基本概念
设计模式
on the way 1231 小时前
行为型设计模式之Interpreter(解释器)
设计模式
cui_hao_nan1 小时前
设计模式——模板方法
java·设计模式
在未来等你1 小时前
Java并发编程实战 Day 11:并发设计模式
java·设计模式·多线程·并发编程·threadlocal·生产者消费者·读写锁
牛奶咖啡132 小时前
学习设计模式《十二》——命令模式
学习·设计模式·命令模式·队列请求·宏命令·可撤销恢复操作·参数化配置
哆啦A梦的口袋呀3 小时前
基于Python学习《Head First设计模式》第七章 适配器和外观模式
python·学习·设计模式
何中应3 小时前
【设计模式-5】设计模式的总结
java·后端·设计模式
季鸢12 小时前
Java设计模式之状态模式详解
java·设计模式·状态模式
smallluan17 小时前
JS设计模式(4):观察者模式
javascript·观察者模式·设计模式