首页 | 源码下载 | 网站模板 | 网页特效 | 广告代码 | 网页素材 | 字体下载 | 书库 | 站长工具
会员投稿 投稿指南 RSS订阅
当前位置:主页>网络编程>java教程>资讯:面向Java开发人员的Scala指南: 增强Scitter库

面向Java开发人员的Scala指南: 增强Scitter库

www.jz123.cn  2009-09-03   来源:   IT专家网    责任编辑(袁袁)    我要投递新闻

连接(到朋友)

  Twitter API 表明,friends_timeline API 调用 “返回认证用户和该用户的朋友发表的最近 20 条状态”。(它还指出,对于直接从 Twitter Web 站点使用 Twitter 的用户,“这相当于 Web 上的 ‘/home’”。)对于任何 Twitter API 来说,这是非常基本的要求,所以让我们将它添加到 Scitter 类中。之所以将它添加到类而不是对象中,是因为正如文档中指出的那样,这是以验证用户的身份做的事情,而我已经决定归入 Scitter 类,而不是 Scitter 对象。

  但是,这里我们碰到一块绊脚石:friends_timeline 调用接受一组 “可选参数”,包括 since_id、max_id、count 和 page,以控制返回的结果。这是一项比较复杂的操作,因为 Scala 不像其他语言(例如 Groovy、JRuby 或 JavaScript)那样原生地支持 “可选参数” 的思想,但是我们首先来处理简单的东西 — 我们来创建一个 friendsTimeline 方法,该方法只执行一般的、非参数化的调用:

  清单 6.“告诉我你身边的朋友是怎样的……”

 


 package com.tedneward.scitter
  {
  class Scitter
  {
  def friendsTimeline : List[Status] =
  {
  val (statusCode, statusBody) =
  Scitter.execute("http://twitter.com/statuses/friends_timeline.xml",
  username, password)
  if (statusCode == 200)
  {
  val responseXML = XML.loadString(statusBody)
  val statusListBuffer = new ListBuffer[Status]
  for (n <- (responseXML \ "status").elements)
  statusListBuffer += (Status.fromXml(n))
  statusListBuffer.toList
  }
  else
  {
  Nil
  }
  }
  }
  }

  到目前为止,一切良好。用于测试的相应方法看上去如下所示:

  清单 7. “我能判断您是怎样的人 ”(Miguel de Cervantes)

 


 package com.tedneward.scitter.test
  {
  class ScitterTests
  {
  // ...
  @Test def scitterFriendsTimeline =
  {
  val scitter = new Scitter(testUser, testPassword)
  val result = scitter.friendsTimeline
  assertTrue(result.length > 0)
  }
  }
  }

  好极了。看上去就像 Scitter 对象中的 publicTimeline() 方法,并且行为也几乎完全相同。

  对于我们来说,那些可选参数仍然有问题。因为 Scala 并没有可选参数这样的语言特性,乍一看来,惟一的选择就是完整地创建重载的 friendsTimeline() 方法,让该方法带有一定数量的参数。

  幸运的是,还有一种更好的方式,即通过一种有趣的方式将 Scala 的两个语言特性(有一个特性我还没有提到过) — case 类和 “重复参数” 结合起来(见清单 8):

  清单 8. “我有多爱你?……”


  package com.tedneward.scitter
  {
  // ...
  abstract class OptionalParam
  case class Id(id : String) extends OptionalParam
  case class UserId(id : Long) extends OptionalParam
  case class Since(since_id : Long) extends OptionalParam
  case class Max(max_id : Long) extends OptionalParam
  case class Count(count : Int) extends OptionalParam
  case class Page(page : Int) extends OptionalParam
  class Scitter(username : String, password : String)
  {
  // ...
  def friendsTimeline(options : OptionalParam*) : List[Status] =
  {
  val optionsStr =
  new StringBuffer("http://twitter.com/statuses/friends_timeline.xml?")
  for (option <- options)
  {
  option match
  {
  case Since(since_id) =>
  optionsStr.append("since_id=" + since_id.toString() + "&")
  case Max(max_id) =>
  optionsStr.append("max_id=" + max_id.toString() + "&")
  case Count(count) =>
  optionsStr.append("count=" + count.toString() + "&")
  case Page(page) =>
  optionsStr.append("page=" + page.toString() + "&")
  }
  }
  val (statusCode, statusBody) =
  Scitter.execute(optionsStr.toString(), username, password)
  if (statusCode == 200)
  {
  val responseXML = XML.loadString(statusBody)
  val statusListBuffer = new ListBuffer[Status]
  for (n <- (responseXML \ "status").elements)
  statusListBuffer += (Status.fromXml(n))
  statusListBuffer.toList
  }
  else
  {
  Nil
  }
  }
  }
  }

  看到标在选项参数后面的 * 吗?这表明该参数实际上是一个参数序列,这类似于 Java 5 中的 varargs 结构。和 varargs 一样,传递的参数数量可以像前面那样为 0(不过,我们将需要回到测试代码,向 friendsTimeline 调用增加一对括号,否则编译器无法作出判断:是调用不带参数的方法,还是出于部分应用之类的目的而调用该方法);我们还可以开始传递那些 case 类型,如下面的清单所示:

  清单 9. “……听我细细说”(William Shakespeare)

  


package com.tedneward.scitter.test
  {
  class ScitterTests
  {
  // ...
  @Test def scitterFriendsTimelineWithCount =
  {
  val scitter = new Scitter(testUser, testPassword)
  val result = scitter.friendsTimeline(Count(5))
  assertTrue(result.length == 5)
  }
  }
  }

  当然,总是存在这样的可能性:客户机传入古怪的参数序列,例如 friendsTimeline(Count(5), Count(6), Count(7)),但是在这里,我们只是将列表传递给 Twitter(希望它们的错误处理足够强大,能够只采用指定的最后那个参数)。当然,如果真的担心这一点,也很容易在构造发送到 Twitter 的 URL 之前,从头至尾检查重复参数列表,并采用指定的每种参数的最后一个参数。不过,后果自负

上一篇:Java Math 类中的新功能(一): 实数 下一篇:通过Java或Jsp向数据库存取二进制图片

评论总数:0 [ 查看全部 ] 网友评论


关于我们隐私版权广告服务友情链接联系我们网站地图