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

如何在Scala中将流畅的界面与功能样式相结合?

发布时间:2020-12-16 18:58:59 所属栏目:安全 来源:网络整理
导读:我在 Java,JavaScript和 Scala一直在阅读OO’流畅的界面’方法,我喜欢它的外观,但一直在努力寻找如何在Scala中使用更基于类型/功能的方法来协调它. 给出一个非常具体的例子:我编写了一个API客户端,可以像这样调用: val response = MyTargetApi.get("orders
我在 Java,JavaScript和 Scala一直在阅读OO’流畅的界面’方法,我喜欢它的外观,但一直在努力寻找如何在Scala中使用更基于类型/功能的方法来协调它.

给出一个非常具体的例子:我编写了一个API客户端,可以像这样调用:

val response = MyTargetApi.get("orders",24)

get()的返回值是一个名为RestfulResponse的Tuple3类型,如我的package object中所定义:

// 1. Return code
// 2. Response headers
// 2. Response body (Option)
type RestfulResponse = (Int,List[String],Option[String])

这工作正常 – 我真的不想牺牲元组返回值的功能简单性 – 但我想用各种’流畅’方法调用来扩展库,可能是这样的:

val response = MyTargetApi.get("customers",55).throwIfError()
// Or perhaps:
MyTargetApi.get("orders",24).debugPrint(verbose=true)

如何将get()返回类型元组(或类似元组)的功能简单性与为我的API添加更多“流畅”功能的能力相结合?

解决方法

您似乎正在处理休息样式通信的客户端API.你的get方法似乎触发了实际的请求/响应周期.看起来你必须处理这个问题:

>传输的属性(如凭据,调试级别,错误处理)
>提供输入数据(您的ID和记录类型(订单或客户))
>对结果做点什么

我认为对于传输的属性,您可以将其中的一些放入MyTargetApi对象的构造函数中,但您也可以创建一个查询对象来存储单个查询的查询对象,并且可以使用查询以流畅的方式进行设置() 方法:

MyTargetApi.query().debugPrint(verbose=true).throwIfError()

这将返回一些有状态的Query对象,该对象存储日志级别的值,错误处理.为了提供输入的数据,您还可以使用查询对象来设置这些值,但不返回响应,而是返回QueryResult:

class Query {
  def debugPrint(verbose: Boolean): this.type = { _verbose = verbose; this }
  def throwIfError(): this.type = { ... }
  def get(tpe: String,id: Int): QueryResult[RestfulResponse] =
    new QueryResult[RestfulResponse] {
       def run(): RestfulResponse = // code to make rest call goes here
    }
}

trait QueryResult[A] { self =>
  def map[B](f: (A) => B): QueryResult[B] = new QueryResult[B] {
    def run(): B = f(self.run())
  }
  def flatMap[B](f: (A) => QueryResult[B]) = new QueryResult[B] {
    def run(): B = f(self.run()).run()
  }
  def run(): A
}

然后最终得到你调用run的结果.所以在一天结束时你可以这样称呼它:

MyTargetApi.query()
  .debugPrint(verbose=true)
  .throwIfError()
  .get("customers",22)
  .map(resp => resp._3.map(_.length)) // body
  .run()

这应该是一个冗长的请求,会在问题上出错,检索id为22的客户,保留正文并将其长度作为Option [Int].

我们的想法是,您可以使用map来定义您尚未拥有的结果的计算.如果我们向其添加flatMap,那么您还可以组合来自两个不同查询的两个计算.

(编辑:李大同)

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

    推荐文章
      热点阅读