Scala:继承与高阶函数

Scala: Inheritance vs Higher order function

假设,

class ClientFunc {
  def client(s: String): Future[Service] = ....

  def m1(s: String) = {
    client(s).map( ...... )
  } 
  ...//there are multiple such methods like m1 in this class which 
depends on "def client".       
}

现在我们必须再添加一个相同类型但实现不同的客户端,我们希望根据需要将其与现有客户端一起使用。

所以有两种方法可以解决这个问题。 解决方案一:使用继承,例如在父级中使客户端方法抽象并为两个不同的客户端提供子级 classA 和 clientB 用于实现。

class clientA extends ClientFunc {
   def client(s: String): Future[Service] = ....
}  
class clientB extends ClientFunc {
   def client(s: String): Future[Service] = ....
} 

照常使用,

 clientAInstance.m1("str")
 and
 clientBInstance.m1("str")

根据用例,我必须一次使用 clientA 和 clientB,因此我需要将两个客户端都注入服务中。

其他解决方案:通过使 "def m1" 之类的功能高阶并在其中传递客户端,保持 ClientFunc class 不变,为其他客户端添加一个功能,例如(def clientB),

class ClientFunc {
  def clientA(s: String): Future[Service] = ....
  def clientB(s: String): Future[Service] = ....

  def m1(s: String, cl:String => Future[Service]) = {
   cl(s).map( ...... )
  } 

}

现在每当我需要打电话时,我都会打电话,

 ClientFuncInstance.m1("str", ClientFuncInstance.clientA)
 and
 ClientFuncInstance.m1("str", ClientFuncInstance.clientB)

不需要两次注入ClientFunc。

问题是在 Scala / 函数式编程中应该首选哪一种方式? & 为什么?如果还有其他更好的方法,请提出建议。

在我看来最好的方法是在构造函数中注入client

class ClientFunc(client: String => Future[Service]) {
  def m1(s: String) = {
    client(s).map( ...... )
  } 
  ...
}

您可以添加新的实现(包括用于测试的模拟)而无需更改现有代码。


[评论后更新]

你会这样使用它:

def clientA(s: String): Future[Service] = ....
def clientB(s: String): Future[Service] = ....

val clientFuncA = new ClientFunc(clientA)
val clientFuncB = new ClientFunc(clientB)

class Service(funcA: ClientFunc, funcB: ClientFunc) {
  def flag = ...
  def client = if (flag) { funcA } else { funcB }

  def m1(s: String) = {
    client.m1(s)
  }
}

val service = new Service(clientFuncA, clientFuncB)