观察者设计模式 - Java 中的观察者模式

位置:首页>文章>详情   分类: Java教程 > 编程技术   阅读(312)   2023-06-26 07:54:18

根据 GoF 的定义,观察者模式定义了对象之间的一对多依赖关系,这样当一个对象改变状态时,它的所有依赖对象都会得到通知并自动更新。它也称为发布-订阅模式

在观察者模式中,有许多观察者(订阅者对象)正在观察一个特定的主题(发布者对象)。观察者将自己注册到一个主题,以便在该主题内部发生更改时收到通知。

观察者对象可以在任何时候从主题注册或注销。它有助于使对象松耦合

1.什么时候使用观察者设计模式

如上所述,当您设计一个系统时,多个实体对某个特定第二实体对象的任何可能更新感兴趣,我们可以使用观察者模式。

观察者模式

观察者模式

流程很容易理解。应用程序创建具体的主题对象。所有具体的观察者都注册自己,以便在主题状态的任何进一步更新中得到通知。

一旦主题的状态发生变化,主题就会通知所有注册的观察者,观察者可以访问更新后的状态并采取相应的行动。

观察者模式序列图

观察者模式时序图

2. 观察者模式的真实世界示例

  • 观察者模式的真实示例可以是任何社交媒体平台,例如 Facebook 或 Twitter。当一个人更新他的状态时——他的所有追随者都会收到通知。

    关注者可以随时关注或取消关注另一个人。一旦取消关注,此人将不会收到来自主题的通知。

  • 在编程中,观察者模式是面向消息的应用程序的基础。当应用程序更新其状态时,它会通知订阅者有关更新的信息。像 HornetQ< 这样的框架/a>,JMS 致力于此模式。
  • 同样,基于 Java UI 的编程,所有键盘和鼠标事件都由其侦听器对象和指定函数处理。当用户单击鼠标时,将调用订阅鼠标单击事件的函数,并将所有上下文数据作为方法参数传递给它。

3.观察者设计模式

3.1.建筑学

观察者模式架构

观察者模式架构

3.2.设计参与者

观察者模式有四个参与者。

  • 主题 – 接口或抽象类 定义将观察者附加和取消附加到主题的操作。
  • ConcreteSubject – 具体的主题类。它维护对象的状态,当状态发生变化时,它会通知附加的观察者。
  • Observer – 定义用于通知此对象的操作的接口或抽象类。
  • ConcreteObserver – 具体的 Observer 实现。

4.观察者设计模式示例

在下面的示例中,我创建了一个 Subject 类型的消息发布者和三个 Observer 类型的订阅者。发布者会定期向所有订阅或附加的观察者发布消息,他们会将更新后的消息打印到控制台。

主题和具体主题

public interface Subject 
{
    public void attach(Observer o);
    public void detach(Observer o);
    public void notifyUpdate(Message m);
}
import java.util.ArrayList;
import java.util.List;

public class MessagePublisher implements Subject {
    
    private List<Observer> observers = new ArrayList<>();

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

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

    @Override
    public void notifyUpdate(Message m) {
        for(Observer o: observers) {
            o.update(m);
        }
    }
}

观察者和具体观察者

public interface Observer 
{
    public void update(Message m);
}
public class MessageSubscriberOne implements Observer 
{
    @Override
    public void update(Message m) {
        System.out.println("MessageSubscriberOne :: " + m.getMessageContent());
    }
}
public class MessageSubscriberTwo implements Observer 
{
    @Override
    public void update(Message m) {
        System.out.println("MessageSubscriberTwo :: " + m.getMessageContent());
    }
}
public class MessageSubscriberThree implements Observer 
{
    @Override
    public void update(Message m) {
        System.out.println("MessageSubscriberThree :: " + m.getMessageContent());
    }
}

状态对象

这必须是一个不可变< /a> 对象,这样任何类都不能错误地修改它的内容。

public class Message 
{
    final String messageContent;
    
    public Message (String m) {
        this.messageContent = m;
    }

    public String getMessageContent() {
        return messageContent;
    }
}

现在测试发布者和订阅者之间的通信。

public class Main 
{
    public static void main(String[] args) 
    {
        MessageSubscriberOne s1 = new MessageSubscriberOne();
        MessageSubscriberTwo s2 = new MessageSubscriberTwo();
        MessageSubscriberThree s3 = new MessageSubscriberThree();
        
        MessagePublisher p = new MessagePublisher();
        
        p.attach(s1);
        p.attach(s2);
        
        p.notifyUpdate(new Message("First Message"));   //s1 and s2 will receive the update
        
        p.detach(s1);
        p.attach(s3);
        
        p.notifyUpdate(new Message("Second Message")); //s2 and s3 will receive the update
    }
}

程序输出。

MessageSubscriberOne :: First Message
MessageSubscriberTwo :: First Message

MessageSubscriberTwo :: Second Message
MessageSubscriberThree :: Second Message

五、常见问题

  • 不同类型的观察者可以注册到一个主题吗?

    观察者的性质和功能可以不同,但​​它们都必须实现一个通用的 Observer 接口,该接口主题支持注册和注销。

  • 我可以在运行时添加或删除观察者吗?

    可以。我们可以随时添加或删除观察者。

  • 观察者模式和责任链模式的区别?

    在观察者模式中,所有已注册的处理程序对象同时获得通知并同时处理更新。

    但在责任链模式中,链中的处理程序对象被一个接一个地通知,这个过程一直持续到一个对象完全处理通知为止。

  • 观察者模式的好处?

    主题和观察者构成了一个松散耦合的系统。他们不需要明确地了解对方。我们可以随时独立添加或删除观察者。

相关 Java 类:

观察者 Java 文档 可观察的 Java 文档

地址:https://www.cundage.com/article/observer-design-pattern.html

相关阅读

Bridge design pattern 用于将一个类解耦为两个部分——抽象和它的实现——这样两者可以在未来发展而不会相互影响。它增加了类抽象与其实现之间的松散耦合。 将抽象与其实现分离,以便...
设计模式是用来解决出现问题的一种模式,大家都知道吧?我们还知道,行为设计模式 是识别对象之间常见通信模式的设计模式。其中一种行为模式是访问者模式,我们将在本文中了解它。 如果您一直在处理管理大量...
Camel Design Patterns 本书包含 20 种模式和大量的设计技术和最佳实践&lt; span style="font-weight: 400;"&gtl;Apache Came...
学习将正则表达式编译成java.util.function.Predicate。当您想对匹配的标记执行某些操作时,这会很有用。 将正则表达式转换为谓词 我有不同域的电子邮件列表,我只想对域名为“...
根据 GoF 的定义,中介者模式 定义了一个对象 封装一组对象如何交互。调解器通过防止对象相互显式引用来促进松散耦合,它让我们可以独立地改变它们的交互。 Mediator 是一种行为设计模式,也...
命令模式 是一种行为设计模式,有助于将业务逻辑抽象为离散的操作,我们称之为命令。此命令对象有助于两个类之间的松散耦合,其中一个类(调用者)应调用另一个类(接收者)上的方法来执行业务操作。 让我们...
在java中创建类实例的最常用方法是什么?大多数人会回答这个问题:“使用新关键字”。好吧,它现在被认为是过时的。看看怎么样?? 如果对象创建代码散布在整个应用程序中,并且如果您需要更改对象创建过...
根据 GoF 的定义,迭代器模式 提供了一种在不暴露其底层表示的情况下按顺序访问聚合对象元素的方法。它是行为设计模式。 顾名思义,迭代器有助于以定义的方式遍历对象集合,这对客户端应用程序很有用。...
Memento 设计模式是行为模式,是四人帮讨论的 23 种设计模式之一。 Memento 模式 用于将对象的状态恢复到以前的状态。它也被称为快照模式。 备忘录就像对象生命周期中的还原点,客户端...
根据 GoF 的定义,观察者模式定义了对象之间的一对多依赖关系,这样当一个对象改变状态时,它的所有依赖对象都会得到通知并自动更新。它也称为发布-订阅模式。 在观察者模式中,有许多观察者(订阅者对...