`
fujohnwang
  • 浏览: 156316 次
社区版块
存档分类
最新评论

Scala Pattern 之 Loan Pattern

阅读更多

Scala Pattern 之 Loan Pattern


Loan Pattern从字面上的来看,意思就是, “ ”贷给“ ”某样东西, 用完后还得还“ ”。 在Scala里面,你可以使用这种模式来实现相应资源的管理和使用。这跟Spring框架里JdbcTemplate+相应Callback的实践很相似, 不过, 在表达上面, 用Scala要更简洁,明确。

因为Java7之后才能用到Closure, 所以,在此之前,Spring给出的Template Method Pattern + Callback的最佳实践, 是我们可以优雅的解决资源管理和使用的最好方式。Java7就好像这个问题的一个分水岭, 有了Java7,你会发现针对这个问题的支持变得那么资源充沛, 因为,Java7里有了Closure,我们再也不用求助于Callback接口和相应的匿名内部类了, 并且, Java7里还专门针对资源的自动管理提供了一种语法糖(Syntactic Sugar), 使得这一问题的表达更简单, 例如:

try (BufferedReader br = new BufferedReader(new FileReader(path)) {  
   return br.readLine();  
}  
 

不过, 说那么多,现在,我们还是得望“Java7 ”止渴,所以,不妨先看看Scala是如何来解决这一问题的。

如果要用Scala来解决这一问题,我们可以定义一个object如下:

package cn.spring21.scalapattern

import java.io.Reader

object LoanPattern {

    def use[T <: Reader,O](resource:T)(func:T=>O){
        try{
            func(resource)
        }finally{
            resource.close
        }
    }
}
 

在LoanPattern对象中,我们定义了一个use方法, 它接受2个参数:

  1. 第一个参数resource类型为T;

  2. 第二个参数func为一个函数定义, 表明它接受一个T类型的参数,返回一个O类型的返回值;

这里有点儿“拗口 ”的就是方法定义use后面的[]中定义的内容, []用来声明参数类型, 类似于Java5之后引入的泛型(Generics)的概念, T <: Reader简单来讲,其实就是说, T类型是java.io.Reader的某种子类型, 从而, use方法定义中就可以把这个类型“ ”给接受T类型参数的函数, 并在函数使用完T类型的资源之后, 关闭它。

有了以上定义之后,我们就可以开始“ ”了, 我们可以如下的形式使用它:

import LoanPattern._
import java.io._		
		
use(new BufferedReader(new FileReader("E:/MyNote.txt"))){
    reader=>
    var line:String = null
    line = reader.readLine
    while(line !=null)
    {
        println(line)
        line = reader.readLine
    }
}
 

import LoanPattern._类似于Java5的static import, 有了它,我们才可以如上的形式来使用use方法,这让它看起来像是语言固有的语法结构, 但实际上,在Scala中,它只是一种常见的对象方法定义而已。use接受2个参数, 第一个参数,我们传入了一个BufferedReader, 第二个则是一个function定义, 我们通过reader => 的形式明确指定了这个function接受的参数名称,然后就可以使用它来读取任何文件了。

Tip
[Tip]

看到这里,有人可能要骂了,这种烂代码也好意思拿出来? 呵呵,实际上, 这里更多的是为了演示的目的, 如果只是简单的读取文件内容并打印,在Scala里面其实更简洁,也更常用的代码是:

println(scala.io.Source.fromFile("E:/MyNote.txt","UTF-8").getLines.mkString)
 

仅此一句话而已。

 

use的定义现在只能负责Reader及其子类相关的资源管理, 但我们可以扩展它,让它变得更加通用,例如:

def use2[T <: {def close();},O](resource:T)(func:T=>O){
    try{
        func(resource)
    }finally{
        resource.close
    }
}
 

use2的定义比use要更进一步, 它可以接受任何定义了close()方法的类型的实例作为资源参数,比如InputStream, OutputStream, Reader, Writer等等,甚至Connection,只要这种类型定义了close()方法就行, 所以,有了它, 剩下的也只是根据情况提供相应的函数定义而已了:

val conn:Connection = dataSource.getConnection
use2(conn){
	val stat:Statement = conn.createStatement
	use2(stat){
		val rs:ResultSet = stat.executeQuery("...")
		use2(rs){
			...// retrieve result data with rs
		}
	}
}
 

简单吧?强大吧?

Tip
[Tip]

Lift框架的作者给出了一条提炼Scala代码的建议,就是尽量减少代码的行数,所以, use或者use2方法可以进一步精炼一下:

def use[T<: Reader,O](resource:T)(func:T=>O){
    try{func(resource)}finally{resource.close}
}
 

甚至于:

def use[T<: Reader,O](resource:T)(func:T=>O) = try{func(resource)}finally{resource.close}
 

当然啦, 应该以尽量不影响代码的可读性为准,也不要让精简后的代码让人阅读起来很费劲为好。

 

Loan Pattern其实是很常见的Pattern, 本文主要关注如何用Scala来表达这一Pattern, 用Ruby之类支持Block/Lambda结构的动态语言当然也可以很容易的表达, 但这已经不是本文要阐述的了。

分享到:
评论

相关推荐

    scala pattern design 设计模式

    ### Scala设计模式详解 #### 一、概述 在软件开发领域,设计模式是解决特定问题的一种通用可重用方案。本书《Scala设计模式》由John Hunt撰写,旨在为读者提供一系列实用的设计模式,并通过Scala语言进行实现。...

    scala pattern match

    在Scala众多强大的特性中,模式匹配(Pattern Matching)是一个非常引人注目的功能,它不仅仅局限于字符串匹配,而是广泛应用于数据结构的解析和组合。 #### 模式匹配的概念 通常当我们提到“模式匹配”时,往往会...

    Scala学习之路(一)

    ### Scala学习之路(一)—— 开发环境搭建与首个程序 #### 一、Scala简介 Scala是一种多范式编程语言,旨在实现可扩展性,并融合了面向对象编程和函数式编程的最佳特性。作为一种与Java非常相似的语言,Scala能够...

    scala3 scala3 scala3 scala3 scala3

    在Scala3中,最重要的变化之一是类型推断的增强。新的Typelevel Scala项目引入了更强大的类型系统,允许编译器更加智能地推断变量和函数的类型,减少了程序员在代码中显式声明类型的需要。例如,`given` 关键字用于...

    scala sdk scala-2.12.3

    Scala SDK,全称为Scala Software Development Kit,是用于开发Scala应用程序的核心工具集。Scala是一种多范式的编程语言,融合了面向对象和函数式编程的特点,它运行在Java虚拟机(JVM)上,能够充分利用Java生态...

    最好的scala学习 课件

    首先,我们从"Scala进阶之路-part01-基础.pdf"开始,这部分内容主要涵盖了Scala的基础知识。你会学习到Scala的语法结构,包括变量声明、常量、数据类型(如基本类型、引用类型、集合类型)、运算符、流程控制语句...

    scala design patterns源书代码

    1. 工厂模式(Factory Pattern):在Scala中,工厂模式可以通过伴生对象和伴生类来实现。这种方式使得创建对象的过程更加灵活,同时也能够隐藏具体的实现细节。 2. 单例模式(Singleton Pattern):Scala中的`...

    大数据技术之Scala.docx

    "大数据技术之Scala" 大数据技术之Scala是指利用Scala语言来处理和分析大数据的一种技术。Scala是一门多范式的编程语言,支持面向对象和函数式编程,运行于Java虚拟机(JVM)之上,可以调用现有的Java类库,实现两...

    scala2.12.1Windows镜像包

    Scala是一种强大的多范式编程语言,它融合了面向...总的来说,"scala2.12.1Windows镜像包"是Windows用户开始Scala编程之旅的基础,通过安装这个包,你可以配置好Scala开发环境,进一步探索这个强大而富有表现力的语言。

    scala实战高清讲解

    - Scala的独特之处在于它允许开发者根据需求自由选择面向对象或函数式编程风格,或者两者的结合。 10. **案例研究** - Spark:Apache Spark是一个基于Scala构建的大数据处理框架,展示了Scala在大数据领域的应用...

    Scala语法简明教程

    - **分布式运行**:Scala设计之初就考虑到了并行和分布式计算的需求,能够很好地支持大规模数据处理和分布式应用程序开发。 - **与Java和C#无缝集成**:Scala能够在JVM上运行,因此可以直接访问Java库,与Java程序...

    scala-2.12.10.zip

    Scala是一种强大的多范式编程语言,它融合了面向对象和函数式编程的概念。这个"scala-2.12.10.zip"文件是Scala编程语言的特定版本——2.12.10,专为Windows操作系统设计的安装包。Scala 2.12.x系列是该语言的一个...

    scala + mybatis 数据库查询

    Scala是一种强大的多范式编程语言,它结合了面向对象和函数式编程的特性。MyBatis则是一款流行的Java持久层框架,主要用于简化数据库操作。在本项目中,"scala + mybatis 数据库查询",我们将探讨如何将Scala与...

    Scala考试题1

    Scala 是一种多范式的编程语言,它融合了面向对象和函数式编程的特性。下面将详细解释题目中涉及的Scala知识点: 1. **var、val 和 def 的区别**: - `var` 定义可变变量,可以多次赋值。 - `val` 定义不可变变量...

    scala-2.12.5.tgz

    另外,该版本还对Pattern Matching进行了优化,使得在处理数据结构时更加灵活和高效。 在函数式编程方面,Scala 2.12.5提供了强大的函数库,包括集合API的增强。这个版本的集合库进一步提升了性能,并且添加了更多...

    scala学习源代码

    Scala是一种强大的多范式编程语言,它融合了面向对象和函数式编程的特性。这个"scala学习源代码"的压缩包文件很可能包含了用于教学或自我学习Scala编程的基础示例。让我们深入了解一下Scala语言的关键概念和特性。 ...

    学习scala好的项目

    Scala是一种强大的多范式编程语言,它融合了面向对象和函数式编程的特性,被广泛应用于大数据处理、分布式计算和Web开发等领域。Spark是基于Scala构建的大数据处理框架,其高性能和易用性使得Scala在大数据领域备受...

    scala-2.11.8.rar

    5. **模式匹配和类型系统**:Scala的模式匹配和强大的类型系统是其独特之处。源码中可以看到这些特性的底层实现。 6. **Scala.js**:虽然在这个特定的压缩包中可能没有,但Scala 2.11.x版本支持Scala.js,可以将...

Global site tag (gtag.js) - Google Analytics