Scala 将类作为函数,并用函数类型声明参数类型,这是否很好?

Scala 将类作为函数,并用函数类型声明参数类型,这是否很好?,scala,testing,functional-programming,Scala,Testing,Functional Programming,我正在从事一个scala项目,我的同事更喜欢函数式,并提出了一种组织代码的方法:将类定义为函数 以下是一个示例: class FetchFeed extends (String => List[Feed]) { def apply(url:String):List[Feed] = ??? } 当其他类需要该类时,将使用类型String=>List[Feed] class MyWork(fetchFeed: String => List[Feed]) 然后在某个地方,将Fet

我正在从事一个scala项目,我的同事更喜欢函数式,并提出了一种组织代码的方法:将类定义为函数

以下是一个示例:

class FetchFeed extends (String => List[Feed]) {
   def apply(url:String):List[Feed] = ???
}
当其他类需要该类时,将使用类型
String=>List[Feed]

class MyWork(fetchFeed: String => List[Feed])
然后在某个地方,将
FetchFeed
传递给它:

val fetchFeed = new FetchFeed
val myWork = new MyWork(fetchFeed)
优点是我们可以通过传递函数轻松模拟
FetchFeed

val myWork = new MyWork(_ => List(new Feed))
语法简单易读

但缺点是,当我看到
MyWork
的声明时:

class MyWork(fetchFeed: String => List[Feed])
很难看到哪个类会被传入,即使IDE也帮不了我。我们需要在代码库中搜索
extends(String=>List[Feed])
,或者找到初始化
新MyWork的位置

如果有另一个类扩展了
String=>List[Feed]
,但从未在
MyWork
中使用过,它常常会让我感到困惑

但是如果我们用实类型声明它:

class MyWork(fetchFeed: FetchFeed)
直接跳转到声明将更容易。但在这种情况下,我们不能直接传递函数,相反,我们需要:

val fetchFeed = mock[FetchFeed]
fetchFeed.apply(any[String]) returns List(new Feed)

val myWork = new MyWork(fetchFeed)

我正在努力解决这两个问题。当以函数式风格编写代码时,这是一种常见的模式吗?是否有任何开源项目采用这种风格,我可以从中获得一些想法?

由于您提到的问题,您所描述的风格并不常见。如果您试图实现函数样式,最好只使用带有类型别名的函数

// Alias the function type to a meaningful name
type FetchFeed = String => List[Feed]

// Declaring an implementation
val fetchFeed: FetchFeed = url => ...

// Nice type name to work with
class MyWork(fetchFeed: FetchFeed)

// Declaring a mock is still easy
new MyWork(_ => List(new Feed))
Scala函数(
A=>B
)可以被视为等同于定义单个
apply(A:A):B
方法的Java接口。那么,您所描述的风格是否与以下风格基本相同:

  • 客户端依赖于一个接口
  • 接口由一个隐藏的具体子类实现
自从Java被发明以来,它就完全是标准的、教科书式的Java风格


回到我整天编写Java的时候,我记得通常使用Eclipses Show Type Hierarchy快捷方式来定位实现子类

感谢您提供此解决方案。它稍微提高了可读性,但是如果4行代码在4个不同的文件中分开,那么当您看到
类MyWork(FetchFeed:FetchFeed)
时,很难找到
FetchFeed
的实现。你可以很容易地跳转到FetchFeed的声明,但是不容易找到实际的实现。你能推荐任何你看到的开源项目,它们可以这样组织代码吗?有效的Scala书籍(来自Twitter)鼓励这种风格()。目前我找不到任何公开的示例。类型别名不能保证静态类型安全;因此,我不会使用这种风格。