内容简介:为了实际说明模板模式在哪些情况下有用,我们假设我们有一个类如下的Resource类:我们的Resouce有一个构造函数,一些访问它的方法以及另一个在不再使用该对象时如何处理它的方法,这些方法可能会像使用数据库或网络连接那样进行冒险操作,然后最终可能会失败抛出RuntimeException。这里通过从10中随机抛出异常来模拟失败的可能性。无论这些方法调用的结果如何,在完成使用资源之后调用dispose()是强制性的,以便释放连接和其他使用了工件,从而避免了内存,连接文件指针泄漏。在这种情况下,使用资源如下.
为了实际说明模板模式在哪些情况下有用,我们假设我们有一个类如下的Resource类:
<b>public</b> <b>class</b> Resource { <b>public</b> Resource() { System.out.println(<font>"Resource created"</font><font>); } <b>public</b> <b>void</b> useResource() { riskyOperation(); System.out.println(</font><font>"Resource used"</font><font>); } <b>public</b> <b>void</b> employResource() { riskyOperation(); System.out.println(</font><font>"Resource employed"</font><font>); } <b>public</b> <b>void</b> dispose() { System.out.println(</font><font>"Resource disposed"</font><font>); } <b>private</b> <b>void</b> riskyOperation() { <b>if</b> ( <b>new</b> Random().nextInt( 10 ) == 0) { <b>throw</b> <b>new</b> RuntimeException(); } } } </font>
我们的Resouce有一个构造函数,一些访问它的方法以及另一个在不再使用该对象时如何处理它的方法,这些方法可能会像使用数据库或网络连接那样进行冒险操作,然后最终可能会失败抛出RuntimeException。这里通过从10中随机抛出异常来模拟失败的可能性。无论这些方法调用的结果如何,在完成使用资源之后调用dispose()是强制性的,以便释放连接和其他使用了工件,从而避免了内存,连接文件指针泄漏。在这种情况下,使用资源如下...
Resource resource = <b>new</b> Resource(); resource.useResource(); resource.employResource(); resource.dispose();
这是错误的, 因为useResoure()或employResource()方法可能最终抛出异常,然后阻止正确处理资源。显然,使用此Resouce的正确方法是这样的:
Resource resource = <b>new</b> Resource(); <b>try</b> { resource.useResource(); resource.employResource(); } <b>finally</b> { resource.dispose(); }
问题是我们无法保证每次使用我们的资源都会按照这种模式正确处理。我们不希望冒被资源被滥用的可能性 - 或者我们希望提供一个API,强制Resource对象的客户端始终处置它。换句话说,我们希望确保资源的客户端始终按照以下模式使用它:
openResource(); <b>try</b> { doSomethingWithResource(); } <b>finally</b> { closeResource(); }
这里我们刚刚定义了一个代码模板,然后我们可以将它放在一个抽象类中:
<b>public</b> <b>abstract</b> <b>class</b> AbstractResourceManipulatorTemplate { <b>protected</b> Resource resource; <b>private</b> <b>void</b> openResource() { resource = <b>new</b> Resource(); } <b>protected</b> <b>abstract</b> <b>void</b> doSomethingWithResource(); <b>private</b> <b>void</b> closeResource() { resource.dispose(); resource = <b>null</b>; } <b>public</b> <b>void</b> execute() { openResource(); <b>try</b> { doSomethingWithResource(); } <b>finally</b> { closeResource(); } } }
此抽象模板封装了我们要强制执行的使用模式,并提供了一种抽象方法,其中不同的具体实现可以定义如何与Resource进行交互。
<b>public</b> <b>class</b> ResourceUser <b>extends</b> AbstractResourceManipulatorTemplate { @Override <b>protected</b> <b>void</b> doSomethingWithResource() { resource.useResource(); } } <b>public</b> <b>class</b> ResourceEmployer <b>extends</b> AbstractResourceManipulatorTemplate { @Override <b>protected</b> <b>void</b> doSomethingWithResource() { resource.employResource(); } }
通过这种方式,在这些具体实现上调用execute()会在Resource上执行各自doSomethingWithResource()方法体中定义的操作,同时确保每次使用它的资源也将被正确处理。
<b>new</b> ResourceUser().execute(); <b>new</b> ResourceEmployer().execute();
提供模板来强制我们的资源的客户端以正确的方式使用它的想法是正确的,但正如我们已经看到的其他模式,GoF书中描述的纯OOP实现是冗长和繁琐的。使用单个方法接受资源消费者,可以直接获得相同的结果。
<b>public</b> <b>static</b> <b>void</b> withResource( Consumer<Resource> consumer) { Resource resource = <b>new</b> Resource(); <b>try</b> { consumer.accept( resource ); } <b>finally</b> { resource.dispose(); } }
请注意,此方法的主体等同于抽象模板的execute()方法所做的,唯一的区别是模板的抽象方法提供的自由度现在通过传递给withResouce()方法的Consumer实现。 。然后,可以用简单的lambda表达式替换定义如何使用Resource的具体模板实现。
withResource( resource -> resource.useResource() ); withResource( resource -> resource.employResource() );
以上所述就是小编给大家介绍的《使用函数式编程重构模板模式》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
xHTML+CSS+Dreamweaver CS3标准网站构建实例详解
李晓斌 / 第1版 (2007年9月1日) / 2007-9 / 49.9
《xHTML+CSS+Dreamweaver CS3标准网站构建实例详解》特别适合网站美工、网站前端架构师、网页设计爱好者、Wap页面设计师作为学习Web标准网页制作的入门图书,也适合Web标准网站高手作为案头随手查询手册,也适合作为美术院校和培训学校相关专业的培训教材。一起来看看 《xHTML+CSS+Dreamweaver CS3标准网站构建实例详解》 这本书的介绍吧!