使用Lambdas重构观察者设计模式

栏目: 后端 · 发布时间: 5年前

内容简介:当某个对象(称为主体)需要在某些事件发生时(例如,状态更改)自动通知其他对象(称为观察者)的列表时,观察者设计模式是一种常见的解决方案。在使用GUI应用程序时,您通常会遇到此模式。您在GUI组件(如按钮)上注册一组观察者。如果单击该按钮,则会通知观察者并执行特定操作。但观察者模式不限于GUI。例如,观察者设计模式也适用于多个交易者(观察者)可能希望对股票(主体)的价格变化作出反应的情况。让我们为Twitter等应用程序设计并实现自定义通知系统。这个概念很简单:几家报社(

当某个对象(称为主体)需要在某些事件发生时(例如,状态更改)自动通知其他对象(称为观察者)的列表时,观察者 设计模式 是一种常见的解决方案。在使用GUI应用程序时,您通常会遇到此模式。您在GUI组件(如按钮)上注册一组观察者。如果单击该按钮,则会通知观察者并执行特定操作。但观察者模式不限于GUI。例如,观察者设计模式也适用于多个交易者(观察者)可能希望对股票(主体)的价格变化作出反应的情况。

让我们为Twitter等应用程序设计并实现自定义通知系统。这个概念很简单:几家报社( NY Times,The Guardian和Le Monde )订阅了新闻推文,如果推文包含特定关键词,可能希望收到通知。

观察者模式:不使用Lambda表达式

步骤1:创建一个 Observer 接口,对不同的观察者进行分组。它只有一个名为 inform的 方法,当有新的推文可供主题(Feed)调用时。

<b>public</b> <b>interface</b> Observer {
     <b>void</b> inform(String tweet);
}

第2步:让我们创建不同的观察者(这里是三份报纸),为包含在推文中的每个不同的关键词产生不同的行动。

<b>public</b> <b>class</b> NYTimes implements Observer{
 @Override
 <b>public</b> <b>void</b> inform(String tweet) {
  <b>if</b>(tweet != <b>null</b> && tweet.contains(<font>"money"</font><font>)){
   System.out.println(</font><font>"Breaking news in NY!"</font><font> + tweet);
  }
 }
}

<b>public</b> <b>class</b> Guardian implements Observer{
 @Override
 <b>public</b> <b>void</b> inform(String tweet) {
  <b>if</b>(tweet != <b>null</b> && tweet.contains(</font><font>"queen"</font><font>)){
   System.out.println(</font><font>"Yet another news in London... "</font><font> + tweet);
  }
 }
}

<b>public</b> <b>class</b> LeMonde implements Observer{
 @Override
 <b>public</b> <b>void</b> inform(String tweet) {
  <b>if</b>(tweet != <b>null</b> && tweet.contains(</font><font>"wine"</font><font>)){
   System.out.println(</font><font>"Today cheese, wine and news! "</font><font> + tweet);
  }
 }
}
</font>

第3步:让我们来定义  主题  接口。

<b>public</b> <b>interface</b> Subject{
 <b>void</b> registerObserver(Observer o);
 <b>void</b> notifyObservers(String tweet);
}

第4步:这是一个非常简单的实现:feed保留一个内部观察者列表,然后它可以在推文到达时通知。

<b>public</b> <b>class</b> Feed implements Subject{
 <b>private</b> <b>final</b> List<Observer> observers = <b>new</b> ArrayList<>();
 <b>public</b> <b>void</b> registerObserver(Observer o) {
  <b>this</b>.observers.add(o);
 }
 <b>public</b> <b>void</b> notifyObservers(String tweet) {
  observers.forEach(o -> o.inform(tweet));
 }
}

第5步:我们现在可以创建一个演示应用程序来连接主题和观察者。

<b>public</b> <b>static</b> <b>void</b> main(String[] args) {
 Feed f = <b>new</b> Feed();
 f.registerObserver(<b>new</b> NYTimes());
 f.registerObserver(<b>new</b> Guardian());
 f.registerObserver(<b>new</b> LeMonde());
 f.notifyObservers(<font>"The queen said her favourite book is Java 8 in Action!"</font><font>);
}
</font>

观察者模式:使用Lambda表达式

请注意,实现 Observer 接口的不同类都提供了单个方法的实现: inform()

当推文到达时,它们只是包裹着一段行为,Lambda表达式专门用于删除该样板。您可以直接传递lambda表达式来表示要执行的行为,而不是显式地实例化三个观察对象:

<b>public</b> <b>static</b> <b>void</b> main(String[] args) {

 Feed feedLambda = <b>new</b> Feed();

 feedLambda.registerObserver((String tweet) -> {
  <b>if</b>(tweet != <b>null</b> && tweet.contains(<font>"money"</font><font>)){
   System.out.println(</font><font>"Breaking news in NY! "</font><font> + tweet); }
 });
 feedLambda.registerObserver((String tweet) -> {
  <b>if</b>(tweet != <b>null</b> && tweet.contains(</font><font>"queen"</font><font>)){
   System.out.println(</font><font>"Yet another news in London... "</font><font> + tweet); }
 });

 feedLambda.notifyObservers(</font><font>"Money money money, give me money!"</font><font>);

}
</font>

我们应该一直使用lambda表达式吗?答案是不!在我们描述的示例中,lambda表达式工作得很好,因为要执行的行为很简单,因此它们有助于删除样板代码。但观察者可能更复杂:他们可能有状态,定义了几种方法等。在这种情况下,你应该坚持使用类模板的样板代码。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

数据结构与算法分析

数据结构与算法分析

维斯 / 人民邮电 / 2006-10 / 59.00元

《数据结构与算法分析:C++描述》秉承Weiss著全一贯的严谨风格,同时又突出了实践。书中充分应用了现代C++语言特性,透彻地讲述了数据结构的原理和应用,不仅使学生具备算法分析能力,能够开发高效的程序,而且让学生掌握良好的程序设计技巧。一起来看看 《数据结构与算法分析》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

SHA 加密
SHA 加密

SHA 加密工具

html转js在线工具
html转js在线工具

html转js在线工具