内容简介:当某个对象(称为主体)需要在某些事件发生时(例如,状态更改)自动通知其他对象(称为观察者)的列表时,观察者设计模式是一种常见的解决方案。在使用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++语言特性,透彻地讲述了数据结构的原理和应用,不仅使学生具备算法分析能力,能够开发高效的程序,而且让学生掌握良好的程序设计技巧。一起来看看 《数据结构与算法分析》 这本书的介绍吧!