我们访问资源需要关注对资源的锁定、对资源的申请和释放,还有考虑可能遇到的各种异常。这些事项本身与代码的逻辑操作无关,但我们不能遗漏。也就是说进入方法时获取资源,退出方法时释放资源。这种处理就进入了Execute Around模式的范畴。

在scala里可以用函数值实现这种模式。下面是一个示例,使用Resource类演示了事务的开启和释放:

class Resource private() {println("Starting transaction...")private def cleanUp() {println("Ending transaction...")}def op1 = println("Operation 1")def op2 = println("Operation 2")def op3 = println("Operation 3")
}object Resource {def use(codeBlock: Resource => Unit) {val resource = new Resource try {codeBlock(resource)} finally {resource.cleanUp()}}
}

这段代码里将Resource类的构造器标记为private,这样就只能在Resource类内部和它的伴生类中创建实例了。因为只能在这两个地方创建实例,从而保证是可以按照确定的方式使用这个类的对象了,也就可以保证其行为是按照确定的方式执行。cleanUp()方法也被标记为private,确保不会被意外调用。第一行的print语句是具体事务操作的占位符。调用构造函数时,事务启动;调用cleanUp()函数时,事务终结。此外Resource类中还准备了一些实例方法,如op1()、op2()等。

在伴生对象里有一个默认public的方法use,它接收一个函数值作为参数。use()方法创建了一个Resource的实例,在try和finally块的保护之下,把这个实例传给了给定的函数值。在finally块里,调用了Resource私有实例方法cleanUp()。

看一下是如何使用Resource类的:

Resource.use { resource =>resource.op1resource.op2resource.op3resource.op1
}

代码输出结果是:

调用Resource的伴生对象时,会自动创建一个Resource实例,等到传递的函数值执行结束后,会自动调用cleanUp方法释放占用的资源。

上面模式的一个变体是Loan模式。如果想确保非内存资源得到确定性释放,就可以使用这个模式。可以这样认为这种资源密集型的对象是借给你的,用过之后应该立即归还。

下面是一个Loan模式的例子:

import java.io._def writeToFile(fileName: String)(codeBlock: PrintWriter => Unit) = {val writer = new PrintWriter(new File(fileName))try {codeBlock(writer)} finally {writer.close()}
}

现在调用writeToFile()将一些内容写入文件:

writeToFile("output.txt") { writer => writer write "hello from Scala" }

方法的执行结果:

作为writeToFile()方法的使用者,我们不必操心文件的关闭。在代码块里,这个文件是借给我们用的。我们可以用得到的PrintWriter实例进行写操作,一旦从这个块返回,方法就会自动关闭文件。

###############

转载于:https://www.cnblogs.com/amunote/p/5720440.html

scala学习手记28 - Execute Around模式相关推荐

  1. scala学习手记34 - trait方法的延迟绑定

    trait的方法的延迟绑定就是先混入的trait的方法会后调用.这一点从上一节的实例中也可以看出来. 下面再来看一个类似的例子: abstract class Writer {def write(me ...

  2. scala学习手记25 - Curry化

    curry翻译为中文就是咖喱.意为使用curry可以让代码更有味道. scala里的curry化可以把函数从接收多个参数转换成接收多个参数列表.也就是说我们要编写的函数不是只有一个参数列表,这个参数列 ...

  3. scala学习手记26 - 重用函数值

    函数值对消除代码重复有很大的帮助.但是像函数值这样直接将一个函数作为另一个函数的参数却不太利于函数值本身的重用. 来看一个例子: class Equipment(val routine: Int =& ...

  4. scala学习手记5 - 元组与多重赋值

    假定要在一个方法中返回多个值.比如需要返回一个人的名.姓和邮箱地址.在Java中最常用的方法是定义一个Person类,其中包括相对应的字段:还有些不常用的方法就是返回一个集合或数组,拿到结果后再进行循 ...

  5. scala学习手记2 - scala中的循环

    先来看一段Java中的循环: for (int i = 1; i < 4; i++) {System.out.print(i + ","); } 毫无疑问,scala可以让这 ...

  6. scala学习-scala读取Hbase表中数据并且做join连接查询

    1.业务需求:sparkSQL on hbase ,sparkSQL直接读取Hbase中的两个表,进行连接查询. 2.图示 绿色的线 上图中绿色的线是做过测试的,直接在hive中建表,然后load数据 ...

  7. R语言学习手记 (1)

    R语言学习手记 (1) 经管的会计和财管都会学数据统计与分析R语言这门课,加上我也有点兴趣,就提前选了这门课,以下的笔记由老师上课的PPT.<R语言编程艺术>和<R语言数据科学> ...

  8. AM335X的汇编语言与c语言,X86汇编语言学习手记 -- 汇编和C协同

    X86汇编语言学习手记(3) 2004年12月 在X86汇编语言学习手记(1)(2)中,可以看到栈(Stack)作为进程执行过程中数据的临时存储区域,通常包含如下几类数据: 局部变量 函数调用的返回地 ...

  9. webpack入门学习手记(一)

    本人微信公众号:前端修炼之路,欢迎关注. 之前用过gulp.grunt,但是一直没有学习过webpack.这两天刚好有时间,学习了下webpack.webpack要想深入研究,配置的东西比较多,网上的 ...

最新文章

  1. date日期相减 java_一个小小的Java程序
  2. system.argumentnullexception值不能为null_MySQL NULL 值如何处理?
  3. 如何使用社会化媒体网络建立个人品牌(国外篇)
  4. 【C语言】输入10个人的成绩,求平均值
  5. 初始分布式事务中间件seata
  6. 将ESXi加入到vCenter中进行管理
  7. python 改文件名字_【Python】按要求修改文件名
  8. Windows Phone开发之路(6) XAML基础(下)
  9. 请勿在计算机室吃带果壳的食品英语,双语者如何在两种语言间切换?
  10. USACO_1_2_Dual Palindromes
  11. HQL (迫切)左外连接
  12. 微信开发者工具安装使用SVN
  13. 这款开源带采集的漫画cms,宅男的大爱
  14. 物联网设备开发中常说的 AT 指令集是什么?
  15. 幼儿-综合素质【2】
  16. 世纪佳缘与百合网结婚了!网络婚恋进入2.0时代 ?
  17. win10专业版进不了安全模式 win10专业版安全模式怎么进
  18. im即时通讯消息id的设计
  19. [笛卡儿积]业务中的复选框条件--输出所有的情况结果
  20. 梁昌勇 软件工程_改进交互式蚁群算法及其应用

热门文章

  1. 【转】Java MySQL数据类型对照
  2. 寒哥细谈之AutoLayout全解
  3. ECNUOJ 2615 会议安排
  4. hdu2457 Trie图+dp
  5. 2.3线性表的链式存储和运算—双向链表
  6. 2012-04-12
  7. 自己动手开发调试器 01
  8. 计算机java考试_2017年计算机java考试试题
  9. mysql几个timeout参数_MySQL中 timeout相关参数解析
  10. Integer对象范围(-128-127)之间(Integer. valueOf()方法)