使用函数式编程重构模板模式

栏目: 编程语言 · 发布时间: 5年前

内容简介:为了实际说明模板模式在哪些情况下有用,我们假设我们有一个类如下的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() );

以上所述就是小编给大家介绍的《使用函数式编程重构模板模式》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

大学的终结

大学的终结

[美] 凯文·凯里(Kevin Carey) / 朱志勇、韩倩 / 人民邮电出版社 / 2017-2-28 / 59.00

你了解目前全球高等教育的现状吗?你知道高等教育的未来是什么样的吗?你听说过泛在大学吗?翻开本书,了解大学的过去、现在与未来。 《大学的终结:泛在大学与高等教育革命》一书由美国著名教育作家凯文? 凯里倾情打造。作者在书中详细论述了美国大学的历史变迁、大学的本质、大学的未来、信息技术与教育的关系、泛在大学的定义、传统大学在大趋势下的挣扎,以及未来高等教育的学历认证与呈现形式。本书作者用缜密的逻辑......一起来看看 《大学的终结》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试