加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala api design:我可以避免不安全的演员表或泛型

发布时间:2020-12-16 10:00:21 所属栏目:安全 来源:网络整理
导读:我正在编写一个提供分布式算法的库.想法是现有的应用程序可以添加库以使用该算法.该算法位于库模块中,它通过网络后面的网络抽象实际数据传输.使用该算法的应用程序必须提供实际的网络传输代码.在代码中,它看起来如下所示: // library is really a separate
我正在编写一个提供分布式算法的库.想法是现有的应用程序可以添加库以使用该算法.该算法位于库模块中,它通过网络后面的网络抽象实际数据传输.使用该算法的应用程序必须提供实际的网络传输代码.在代码中,它看起来如下所示:

// library is really a separate project not a single object
object Library {

  // handle to a remote server
  trait RemoteProcess

  // concrete server need to know how to actually send to a real remote process
  trait Server {
    def send(client: RemoteProcess,msg: String)
  }
}

// the application uses the library and provides the concrete transport
object AkkaDemoApplication {

  // concreate ref is a m wrapper to an actor ref in demo app
  case class ConcreteRemoteProcess(ref: akka.actor.ActorRef) extends Library.RemoteProcess

  class AkkaServer extends Library.Server {
    // **WARNING** this wont compile its here to make my question
    override def send(client: ConcreteRemoteProcess,msg: String): Unit = client.ref ! msg
  }
}

我考虑过几个选项:

>让AkkaServer方法的签名重载库特征方法,然后对ConcreteRemoteProcess执行不安全的转换.育!
>让AkkaServer方法的签名重载库特征方法,然后在RemoteProcesss参数上进行模式匹配,得到一个ConcreteRemoteProcess.如果传递错误的东西,这在运行时爆炸方面并不比不安全的强制转换更好.
>根据RemoteProcess使库服务器通用.

选项3的示例如下所示:

object Library {

  trait Server[RemoteProcess] {
    def send(client: RemoteProcess,msg: String)
  }
}

object Application {
  class AkkaServer extends Library.Server[ActorRef] {
    override def send(client: ActorRef,msg: String): Unit = client ! msg
  }
}

我尝试了选项3并且它工作但是泛型类型最终被标记在整个库模块的几乎每种类型上.然后有很多协变和逆变的麻烦来编译算法代码.只是为了在一个集成点获得编译时确定性,认知开销非常大.在视觉上,库代码由通用签名控制,就好像理解对于理解库是至关重要的,实际上它完全分散了解库逻辑.

因此,使用遗传工作并给我编译时间肯定,但现在我希望我选择2(模式匹配)的借口“它会在启动时快速失败,如果有人弄错了让我们保持简单”.

我是否缺少一些Scala功能或成语,以获得编译时确定性而没有所有库代码触及但忽略的“高触摸”泛型的认知开销?

编辑我已经考虑过,或许我的代码库被严重考虑因为重构可以将泛型移动到边界.然而,该库已经被重构为可测试性,并且分解为可测试的职责是泛型问题的一部分,这些问题在代码库中被涂抹了.因此我的问题是:一般来说还有另一种技术我不知道要避免泛型为抽象API提供具体的实现吗?

解决方法

我认为你的算法与Akka的结合太紧密了.此外,我假设服务器将数据发送到执行某些操作的远程客户端并发回结果

回答

为什么不

object Library {
  // handle to a remote server
  trait RemoteProcessInput

  trait RemoteProcessResult

  // concrete server need to know how to actually send to a real remote process and how to deal with the result
  trait Server {
    def handle(clientData: RemoteProcessInput) : Future[RemoteProcessResult] 
  }
}

具体实现提供了Akka的实现

object Application {
  class AkkaServerImpl(system: ActorSystem)
  extends Library.Server {
    override def handle(clientData: RemoteProcessInput)
  : ActorRef,msg: String): Future[RemoteProcessResult] = {
      // send data to client and expect result
      // you can distinguish target and msg from the concrete input
      val ref : ActorRef = ??? // (resolve client actor)
      val msg = ??? // (create your message based on concrete impl)
      val result = ref ? msg // using ask pattern here
                             // alternatively have an actor living on server side that sends msgs and receives the clients results,triggered by handle method
      result
    } 
}

}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读