scala :::_Scala:缺少OO和FP桥

scala :::

Scala以许多不错的方式将功能和面向对象的编程融合在一起。 您可以同时使用FP和OO类结构,以更好地解决当前问题。 但是总有改进的空间! 这是我认为缺少的一件事(底部是简短版本 )。

FP侧

在Scala中将方法转换为函数很容易。 例如,如果您有一个方法:

def say(to: Person, what: String): String = { ... }

我们可以使用下划线符号获取相应的功能:

val sayFun: (Person, String) => String = say _

而且,Scala支持多个参数列表,有时也称为currying ,这使得部分应用更加容易:

// Method with multiple parameter list
def connect(person1: Person)(person2: person): Connection = { ... }
// Function, created by partially applying the previous method
val createConnectionWithAdam: Person => Connection =
      connect(new Person('Adam')) _

面向对象的一面

每个类都有一件事是构造函数。 但是什么是构造函数呢? 您可以为构造函数的参数指定值,然后获取该类的新实例。 因此,它实际上只是一个功能!

class Person(name: String, age: Int) { ... }
// The 'signature' of new is (String, Int) => Person
val somebody = new Person('John', 34)

链接?

但是,这就是OO和FP组合在Scala中失败的地方:不能将上述方法的两个功能(转换为函数,currying)与构造函数一起使用。 这两个都不起作用

val makePerson: (String, Int) => Person = new Person _

class Person2(name: String)(age: Int) { ... }
val makeNewJack: Int => Person = new Person2('Jack') _

您可以使用伴随对象解决此问题并apply (或任何其他工厂方法,应用之后会有一个更好的表示法):

object Person2 {
   def apply(name: String)(age: Int) = new Person2(name, age)

}
val makeNewJack: Int => Person = Person2('Jack') _

但这需要在同伴对象中重复构造函数的签名,没有人喜欢重复代码,对吗? ;)

用例

这在哪里有用? 例如在经典工厂示例中。 假设您有一个类,它依赖于某些服务,但也依赖于运行时可用的某些数据。 当然,我们使用IoC,因此向我们的班级提供了其他服务的实例:

// This service depends on a concrete Person instance
class Service3(service1: Service1, service2: Service2)(person: Person) {
...
}
/ Note that the multiple parameter notation above als provides a nice
// separation of the parameters that should be 'injected' - services,
// and the data that can be variable.
// This service depends on Service1, and wants to create it having Person
// instances
class Service4(makeService3: Person => Service3) {
  // Usage:
  for (person <- persons) makeService3(person).doSomething()
}
class Main {
      // Bootstrap: (or - no-framework DI container ;) )
         val service1 = new Service1
         val service2 = new Service2
      // That's the part that is illegal in Scala
         val makeService3 = new Service3(service1, service2) _
         val service4 = new Service4(makeService1)
...
// Today we'd have to write: val makeService3 = (person: Person) => new Service3(//service1, service2, person)
}

这也与我在DI和OO上的文章有关,以及当前的DI框架如何难以定义依赖于我们希望拥有多个副本的数据和服务的服务。

边注

当将构造函数视为方法/函数时(实际上是;)),我假设使用类似Ruby的符号:

Person.new('John', 34)

会更好,并且增加对_和多个参数列表的支持将是显而易见的。

TL; DR风扇的底线

为什么不将类构造函数与其他所有方法/函数一样对待? 使其合法:

class Person(name: String, age: Int)
val makePerson = new Person _ // type: (String, Int) => Person

class Person2(name: String)(age: Int)
val makeNewJack = new Person2('Jack') _ // type: Int => Person

参考: 我们的JCG合作伙伴 Adam Warski的博客中, 缺少Scala中的OO和FP桥接器


翻译自: https://www.javacodegeeks.com/2012/08/scala-missing-oo-and-fp-bridge.html

scala :::

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值