Observable设计模式简介

译者 | 蔡柱梁策划 | 言征Observable设计模式存在于许多Java API和响应式编程中。下面介绍Java中永恒的Observable模式。  
Observable设计模式用于许多重要的Java API。一个众所周知的示例是使用ActionListenerAPI执行操作的JButton。在这个例子中,我们ActionListener在按钮上进行了监听或观察。单击按钮时,ActionListener将执行操作。
Observable模式也用于响应式编程。在反应式应用程序中使用观察者是有道理的,因为反应式的本质是反应:当另一个进程发生时,事情就会发生。
Observable是一种行为设计模式。它的功能是在事件发生时执行一个动作。两个常见的例子是按钮点击和通知,但这种模式还有更多用途。

Observable模式的一个例子


在Observable模式中,一个对象在执行操作时通知另一个对象。为了理解该模式的价值,让我们想象一个需要单击按钮并且没有通知另一个对象的场景,如图1所示。


请注意,ActionCheck必须每秒检查一次按钮。现在,想象一下,如果我们每秒对该按钮进行多次操作检查。您能想象这会对您的应用程序性能产生什么影响吗?
让Do Something按钮通知ActionCheck.这样,ActionCheck逻辑就不需要每秒轮询Do Something按钮。

Observable设计模式的元素


在下图中,请注意观察者模式的基础是Observer接口(即观察的对象)和Subject(被观察的对象)。类NewsletterimplementsSubject和Subscriberimplements Observer。最后,SendEmailMain执行Observable设计模式。


代码中的Observable模式


Subject接口,也称为Observableor Publisher,是Observable设计模式的基础。基本上,它存储观察者并在观察到的动作发生时立即通知他们。看一下Subject界面。
public interface Subject {

   void addSubscriber(Observer observer);
   void removeSubscriber(Observer observer);
   void notifySubscribers();

}

观察者界面


接口(Observer有时也称为Subscriber)由订阅者实现,它试图观察是否已执行操作:
public interface Observer {

   public void update(String email);

}

行动中可观察


让我们用一个时事通讯的例子来实现这个Subject接口。在下面的代码中,我们存储我们的观察者(在本例中为时事通讯订阅者),并且当他们的电子邮件被添加到订阅时,每个订阅者都会收到通知。
import java.util.ArrayList;
import java.util.List;

public class Newsletter implements Subject {

   protected List<Observer> observers = new ArrayList<>();
   protected String name;
   protected String newEmail;

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

   public void addNewEmail(String newEmail) {
       this.newEmail = newEmail;
       notifySubscribers();
   }
左右滑动查看完整代码
@Override
public void addSubscriber(Observer observer) {
       observers.add(observer);
   }
左右滑动查看完整代码
 @Override
public void removeSubscriber(Observer observer) {
       observers.remove(observer);
   }
左右滑动查看完整代码
 @Override
public void notifySubscribers() {
       observers.forEach(observer -> observer.update(newEmail));
   }
}

左右滑动查看完整代码


订阅者


Subscriber类表示订阅电子邮件时事通讯的用户。此类实现了Observer接口。它是我们将观察的对象,以便我们知道是否发生了事件。
class Subscriber implements Observer {

 private String name;

 public Subscriber(String name) {
   this.name = name;
 }
 @Override
 public void update(String newEmail) {
   System.out.println("Email for: " + name + " | Content:" + newEmail);
 }

}

左右滑动查看完整代码


发送邮件主


现在我们有了使Observable模式有效工作的主类。首先,我们将创建Newsletter对象。然后,我们将添加和删除订阅者。最后,我们将添加一封电子邮件并通知订阅者他们的状态。
public class SendEmailMain {

 public static void main(String[] args) {
   Newsletter newsLetter = new Newsletter("Java Challengers");

   Observer duke = new Subscriber("Duke");
   Observer juggy = new Subscriber("Juggy");
   Observer dock = new Subscriber("Moby Dock");

   newsLetter.addSubscriber(duke);
   newsLetter.addNewEmail("Lambda Java Challenge");
   newsLetter.removeSubscriber(duke);

   newsLetter.addSubscriber(juggy);
   newsLetter.addSubscriber(dock);
   newsLetter.addNewEmail("Virtual Threads Java Challenge");
 }

}

左右滑动查看完整代码


这是我们代码的输出:
Email for: Duke | Content:Lambda Java Challenge
Email for: Juggy | Content:Virtual Threads Java Challenge
Email for: Moby Dock | Content:Virtual Threads Java Challenge

左右滑动查看完整代码


何时使用Observable模式


当一个动作发生并且需要通知多个对象时,最好使用Observable模式而不是Object多次检查状态。想象一下,有 200多个对象需要接收通知;在这种情况下,您必须将200乘以检查发生的次数。
通过使用Observable模式,通知只会对所有订阅者发生一次。这是一个巨大的性能提升,也是一种有效的代码优化。此代码可以轻松扩展或更改。
反应式编程范式到处都使用Observable模式。如果您曾经使用过Angular,那么您就会知道使用Observable组件非常普遍。响应式组件经常被其他事件和逻辑观察到,当满足特定条件时,组件将执行一些动作。

结论


以下是关于Observable设计模式,需要记住的要点:
  • Observable使用开闭SOLID原则。这意味着我们可以扩展addSubscriber和removeSubscriber方法而无需更改方法名。原因是它接收的是Subject接口而不是直接实现。
  • Observer界面观察发生在Subject。
  • Subject也被称为可观察对象,因为它是一个将被观察的主题。它也可以称为发布器,因为它发布事件。
  • Observer也被称为订阅者,因为它订阅了主题/发布者。操作发生时通知观察者。
  • 如果我们不使用Observable设计模式,订阅者将不得不不断轮询以了解是否发生了事件,这可能会对应用程序性能造成严重影响。Observable是一个更有效的解决方案。

原文链接:

https://www.infoworld.com/article/3682139/intro-to-the-observable-design-pattern.html



蔡柱梁,51CTO社区编辑,从事Java后端开发8年,做过传统项目广电BOSS系统,后投身互联网电商,负责过订单,TMS,中间件等。

相关推荐

  • Node.js应用全链路追踪技术——[全链路信息获取]
  • ChatGPT保姆级注册教程,速速收藏!
  • 世卫:强震或致土叙2300万人受影响;太平洋上“漂着”3.2吨可卡因;全球首架国产大飞机C919飞抵三亚 | 每日大新闻
  • 正面刚ChatGPT,谷歌发布Bard! AI们要battle起来了?
  • 即时通讯行业首个《安全合规白皮书》发布
  • 15年做不好的代码搜索,用Rust重写搞定:GitHub声称能从此“改变游戏规则”
  • 春上新丨给大家找来了50多块钱的基础款,质量做工都不错
  • 准备跳槽了。。
  • 8 个线程池最佳实践和坑!使用不当直接生产事故!!
  • “激吻门”10年后,潘粤明“整容式”现状曝光:他终于活成董洁配不上的样子
  • 我用微软新Bing写了封求职信
  • Chat GPT会不会让底层程序员失业?
  • 百度官宣类ChatGPT大模型新项目:文心一言
  • 中国开源社区健康案例——Apache Dubbo社区
  • 我们谈到了《流浪地球2》正版周边,官方授权!
  • 清华最新《持续学习》综述,32页pdf详述持续学习理论、方法与应用综述
  • 跨平台开发,Flutter还是React Native?
  • ChatGPT一出,这10大职业可能先丢饭碗
  • 盛产“神药”的石家庄,为何还圆不了“药都”梦?
  • 一个和老板对着干的综艺,竟收割不少网友简历?