设计模式—观察者模式与发布订阅

观察者设计模式

观察者设计模式(Observer Design Pattern)是一种常用的软件设计模式,它是一种行为型模式。该模式用于定义对象之间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知并自动更新。

结构

观察者模式通常涉及以下几个角色:

  1. Subject(主题):主题是被观察的对象,它包含了需要被观察的状态。当主题状态发生变化时,它会通知所有的观察者对象。

  2. Observer(观察者):观察者是依赖于主题的对象,它们将在主题状态发生变化时得到通知,并进行相应的更新操作。

  3. ConcreteSubject(具体主题):具体主题是主题的具体实现,它维护了一组观察者对象,并在状态发生改变时通知它们。

  4. ConcreteObserver(具体观察者):具体观察者实现了观察者接口,在收到主题通知时执行特定的更新操作。

示例

以下是一个简单的观察者模式的示例,假设我们有一个主题(Subject)代表气象站,而观察者(Observer)是一组天气显示板,它们会在气象站更新数据时自动更新显示:

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

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

// 观察者接口
interface Observer {
    void update(float temperature, float humidity, float pressure);
}

// 具体主题
class WeatherData implements Subject {
    private List<Observer> observers;
    private float temperature;
    private float humidity;
    private float pressure;

    public WeatherData() {
        observers = new ArrayList<>();
    }

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

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

    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(temperature, humidity, pressure);
        }
    }

    public void measurementsChanged() {
        notifyObservers();
    }

    public void setMeasurements(float temperature, float humidity, float pressure) {
        this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
        measurementsChanged();
    }
}

// 具体观察者
class CurrentConditionsDisplay implements Observer {
    private float temperature;
    private float humidity;

    public void update(float temperature, float humidity, float pressure) {
        this.temperature = temperature;
        this.humidity = humidity;
        display();
    }

    public void display() {
        System.out.println("Current conditions: " + temperature + "F degrees and " + humidity + "% humidity");
    }
}

// 测试
public class WeatherStation {
    public static void main(String[] args) {
        WeatherData weatherData = new WeatherData();
        
        CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay();
        
        weatherData.registerObserver(currentDisplay);
        
        weatherData.setMeasurements(80, 65, 30.4f);
    }
}

发布订阅者模式

发布-订阅者模式(Publish-Subscribe Pattern)是一种软件设计模式,用于实现消息的发布和订阅机制,也被称为观察者模式的变体。在发布-订阅者模式中,消息的发布者(发布者)和消息的接收者(订阅者)之间没有直接的依赖关系,它们通过一个称为"消息代理"或"事件总线"的中介来进行通信。这种模式允许组件之间松耦合地通信,从而提高系统的可扩展性和灵活性。

结构

发布-订阅者模式通常包括以下几个关键部分:

  1. 发布者(Publisher):负责发布消息或事件到消息代理。

  2. 订阅者(Subscriber):注册对特定类型的消息或事件感兴趣,并在消息到达时执行相应的操作。

  3. 消息代理(Message Broker):作为发布者和订阅者之间的中介,负责管理消息的路由和传递。它维护了发布者和订阅者之间的关系,并在消息到达时将消息传递给所有订阅者。

示例

以下是一个简单的发布-订阅者模式的示例,假设我们有一个新闻发布系统,包括新闻发布者和新闻订阅者:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

// 消息代理
class MessageBroker {
    private Map<String, List<Subscriber>> topics = new HashMap<>();

    public void subscribe(String topic, Subscriber subscriber) {
        topics.computeIfAbsent(topic, k -> new ArrayList<>()).add(subscriber);
    }

    public void publish(String topic, String message) {
        List<Subscriber> subscribers = topics.get(topic);
        if (subscribers != null) {
            for (Subscriber subscriber : subscribers) {
                subscriber.receive(message);
            }
        }
    }
}

// 订阅者接口
interface Subscriber {
    void receive(String message);
}

// 新闻订阅者
class NewsSubscriber implements Subscriber {
    private String name;

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

    public void receive(String message) {
        System.out.println(name + " received news: " + message);
    }
}

// 新闻发布者
class NewsPublisher {
    private MessageBroker messageBroker;

    public NewsPublisher(MessageBroker messageBroker) {
        this.messageBroker = messageBroker;
    }

    public void publishNews(String topic, String news) {
        messageBroker.publish(topic, news);
    }
}

// 测试
public class NewsSystem {
    public static void main(String[] args) {
        MessageBroker messageBroker = new MessageBroker();
        
        NewsPublisher publisher = new NewsPublisher(messageBroker);
        publisher.publishNews("sports", "New record set in 100m sprint!");
        publisher.publishNews("technology", "New smartphone announced!");
        
        NewsSubscriber subscriber1 = new NewsSubscriber("John");
        NewsSubscriber subscriber2 = new NewsSubscriber("Alice");
        
        messageBroker.subscribe("sports", subscriber1);
        messageBroker.subscribe("technology", subscriber2);
        
        publisher.publishNews("sports", "Team wins championship!");
    }
}

发布-订阅者模式在事件驱动的系统中非常有用,它可以使系统中的各个组件彼此解耦,并提供一种灵活的通信机制。

观察者vs发布订阅

 

相关推荐

  1. js设计模式--发布订阅模式

    2024-03-22 23:30:01       10 阅读
  2. 发布订阅模式观察模式详解

    2024-03-22 23:30:01       36 阅读
  3. 观察模式发布-订阅模式有什么异同

    2024-03-22 23:30:01       21 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-22 23:30:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-22 23:30:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-22 23:30:01       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-22 23:30:01       20 阅读

热门阅读

  1. GPT+向量数据库+Function calling=垂直领域小助手

    2024-03-22 23:30:01       16 阅读
  2. node核心模块之Path

    2024-03-22 23:30:01       19 阅读
  3. php函数参考表

    2024-03-22 23:30:01       17 阅读
  4. c语言:于龙减

    2024-03-22 23:30:01       18 阅读
  5. 【蓝桥杯入门记录】模板1.0

    2024-03-22 23:30:01       18 阅读
  6. postgres数据库中的几种常用的几何空间运算

    2024-03-22 23:30:01       17 阅读
  7. 大模型常见面试题及解答

    2024-03-22 23:30:01       19 阅读
  8. Leetcode 459:重复的子字符串

    2024-03-22 23:30:01       18 阅读
  9. Pulsar集成Debezium监听MySQL日志

    2024-03-22 23:30:01       18 阅读