内容简介:当某个对象(称为主体)需要在某些事件发生时(例如,状态更改)自动通知其他对象(称为观察者)的列表时,观察者设计模式是一种常见的解决方案。在使用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表达式工作得很好,因为要执行的行为很简单,因此它们有助于删除样板代码。但观察者可能更复杂:他们可能有状态,定义了几种方法等。在这种情况下,你应该坚持使用类模板的样板代码。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Transcending CSS
Andy Clarke、Molly E. Holzschlag / New Riders / November 15, 2006 / $49.99
As the Web evolves to incorporate new standards and the latest browsers offer new possibilities for creative design, the art of creating Web sites is also changing. Few Web designers are experienced p......一起来看看 《Transcending CSS》 这本书的介绍吧!