什么是“特质允许组成”?

时间:2013-12-10 14:29:35

标签: scala composition traits

我正在阅读“Scala in depth”一书的第一部分。在第一部分中,它给出了一个将java JdbcTemplate接口转换为scala:

的示例

Java代码:

public interface JdbcTemplate {
  List query(PreparedStatementCreator psc,
    RowMapper rowMapper)
}

Scala代码:

trait JdbcTemplate {
  def query[ResultItem](psc : Connection => PreparedStatement,
                        rowMapper : (ResultSet, Int) => ResultItem) : List[ResultItem]
}

然后它说:

  

通过一些简单的转换,我们创建了一个直接与函数相关的接口。这是一种更具功能性的方法,因为scala的功能特性允许组合。当你读完这本书时,你将能够完全不同地接近这个界面的设计。

我无法理解“traits allow composition”,因为我在提供的示例中找不到任何“组合”。

我会错过什么吗?

3 个答案:

答案 0 :(得分:3)

你错过了这句话的第一部分:

  

scala的功能特征允许合成

在scala函数中是一个简单的对象,由Function[-T, +R]等特征构成,在所有这些特征上,你有两种方法:andThencompose

答案 1 :(得分:1)

您的代码段不是组合样本,但允许进行合成。事实上,仅trait只能构成......本身:)

Trait允许在运行时通过with关键字进行撰写 基本上,它允许将特征的方法添加到关联的traitclass甚至...运行时对象!
已知组合是运行时特征(其主要优点),并且已知继承是编译特征,因此是静态的。

以下是在运行时使用trait组合的示例:

val obj1 = new MyClass() with JdbcTemplate
//obj1.query .......

与Java相比,如果MySuperClassclassabstract class,您仍然可以通过实施某种策略模式等在运行时从其他地方添加/更改行为......但是它需要你描述一个接口+实现。硼 相反,Trait允许在一个地方定义方法。

这就是为什么在scala中,trait被称为“允许组合”,显然,函数式编程概念更适合于组合而不是继承。

更新----------------------

@Alexlv是对的=>重要的一个词是Scala的 FUNCTION 特征。 我的上述解释仍然正确,但不符合作者的意思 恕我直言,他想说:Connection => PreparedStatement是一个Function1,并且由于函数喜欢组合,它可以从函数式编程字中提供一些很好的处理,以生成所需的query方法参数。

答案 2 :(得分:0)

作者的观点是用函数类型替换PreparedStatementCreatorRowMapper会产生更多功能的API(惊喜!)。 API更好地支持代码重用,因为pscrowMapper函数可以由简单的功能组件组成。例如,您可能拥有filter ResultSet,提取各种数据,转换数据(map),汇总数据(fold)等功能。

正如@Alexiv指出的那样,所有Scala函数对象(通过各种Function特征)都提供了支持函数组合的andThencompose方法。