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

栏目: 编程语言 · 发布时间: 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() );

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

查看所有标签

猜你喜欢:

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

人工智能

人工智能

(美)GeorgeF.Luger / 郭茂祖;刘扬;玄萍;王春宇 / 机械工业出版社 / 2010-1 / 79.00元

《人工智能复杂问题求解的结构和策略(原书第6版)》是一本经典的人工智能教材,全面阐述了人工智能的基础理论,有效结合了求解智能问题的数据结构以及实现的算法,把人工智能的应用程序应用于实际环境中,并从社会和哲学、心理学以及神经生理学角度对人工智能进行了独特的讨论。新版中增加了对“基于随机方法的机器学习”的介绍,并提出了一些新的主题,如涌现计算、本体论、随机分割算法等。 《人工智能复杂问题求解的结......一起来看看 《人工智能》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器