simple-rest-scala中Book.scala文件内容背后的原因是什么?

时间:2015-04-20 12:04:42

标签: scala api rest playframework-2.0

activator template for simple rest API project in Scala中,Book.scala文件如下所示。

package models

import play.api.libs.json.Json

object Book {

  case class Book(name: String, author: String)

  implicit val bookWrites = Json.writes[Book]
  implicit val bookReads = Json.reads[Book]

  var books = List(Book("TAOCP", "Knuth"), Book("SICP", "Sussman, Abelson"))

  def addBook(b: Book) = books = books ::: List(b)
}

为什么里面有Book个对象和Book个案例类?为什么不只是一个Book案例类(或只是一个Book类而不是一个案例类)?上述结构有哪些优点/缺点?

2 个答案:

答案 0 :(得分:2)

我确信这只是某个人放在一起的一个小例子,所以你不应该读太多。但它展示了一些人认为的反模式:在其他类中嵌套案例类。一些最佳实践指南,例如this one,建议避免在其他类中嵌套案例类,并且有充分的理由:

  

这很诱人,但你几乎不应该定义嵌套的case类   在另一个对象/类中,因为它与Java混淆   序列化。原因是当你序列化一个case类时   关闭“this”指针并序列化整个对象   如果你输入你的App对象意味着每个实例   案例类,你序列化整个世界。

     

具体案例类的内容是:

     
      
  1. 我希望案例类是不可变的(值,事实),因此
  2.   
  3. 我希望案例类可以轻松序列化
  4.         

    首选平面层次结构。

例如,这个小程序会出乎意料地抛出异常:

import java.io._

class Outer {
  case class Inner(a: Int)
}

object Test extends App {
    val inner = (new Outer).Inner(1)
    val oos = new ObjectOutputStream(new FileOutputStream("/tmp/test"))
    oos.writeObject(inner)
    oos.close
}

如果此外部Book对象的唯一目的是将常用功能组合在一起,则package将是首选结构。

此外,即使由于某些其他原因需要object,将该对象命名为与内部案例类相同也会造成混淆,特别是因为案例类会自动生成伴随对象。因此,在此示例中,有一个Book对象,一个Book.Book案例类,因此还有Book.Book个伴随对象。

答案 1 :(得分:1)

Book对象在此代码中的作用更像是一个静态书籍utils / manager类,它包含一系列书籍。你可以想象这是一个库类,允许添加书籍。

Book case类只是Book实例的匿名类。正如m-z所说,这只是一个例子,对于更复杂的类,你可以把它移到一个独立的Book类。