如何在Scala中将流畅的界面与功能样式相结合?
我在
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方法似乎触发了实际的请求/响应周期.看起来你必须处理这个问题:
>传输的属性(如凭据,调试级别,错误处理) 我认为对于传输的属性,您可以将其中的一些放入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,那么您还可以组合来自两个不同查询的两个计算. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |