内容简介:为了实际说明模板模式在哪些情况下有用,我们假设我们有一个类如下的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() );
以上所述就是小编给大家介绍的《使用函数式编程重构模板模式》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
精通CSS与HTML设计模式
Michael Bowers / 刘申 朱瑜敏 鲁奇 / 人民邮电出版社 / 2008-9 / 69.00元
本书是一部非常实用的CSS 与HTML(XHTML)解决方案手册。书中包含了350 多种可以立即使用的设计模式(涉及文本、背景、边框、图片、表格、布局等多方面),并介绍了每种模式的原理和使用。每种设计模式、示例和源代码都经过了精心设计,易于实现和使用。通过阅读此书,可大大提高读者在 Web 设计和开发中的效率和创造力。 本书结构清晰,示例丰富,实践性强,适用于所有Web 开发和设计人员......一起来看看 《精通CSS与HTML设计模式》 这本书的介绍吧!