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

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

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

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

查看所有标签

猜你喜欢:

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

Hacking

Hacking

Jon Erickson / No Starch Press / 2008-2-4 / USD 49.95

While other books merely show how to run existing exploits, Hacking: The Art of Exploitation broke ground as the first book to explain how hacking and software exploits work and how readers could deve......一起来看看 《Hacking》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具