内容简介:当某个对象(称为主体)需要在某些事件发生时(例如,状态更改)自动通知其他对象(称为观察者)的列表时,观察者设计模式是一种常见的解决方案。在使用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表达式工作得很好,因为要执行的行为很简单,因此它们有助于删除样板代码。但观察者可能更复杂:他们可能有状态,定义了几种方法等。在这种情况下,你应该坚持使用类模板的样板代码。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
游戏编程权威指南
Mike McShaffry 麦克沙福瑞、David “Rez” Graham 格雷海姆 / 师蓉、李静、李青翠 / 人民邮电 / 2016-3 / 99.00元
全书分为4个部分共24章。首部分是游戏编程基础,主要介绍了游戏编程的定义、游戏架构等基础知识。 第二部分是让游戏跑起来,主要介绍了初始化和关闭代码、主循环、游戏主题和用户界面等。 第三部分是核心游戏技术,主要介绍了一些*为复杂的代码 示例,如3D编程、游戏音频、物理和AI编程等。 第四部分是综合应用,主要介绍了网络编程、多道程序设计和用C#创建工具等,并利用前面所讲的 知识开发出......一起来看看 《游戏编程权威指南》 这本书的介绍吧!