Scala:值参数与懒惰的xml

时间:2012-05-23 23:07:12

标签: xml scala lazy-evaluation

我正在尝试使用Scala解析来自artist.getInfolast.fm来电。 scala的Xml API真的很棒,但我有一个设计问题(也许是个人风格)。

目前,我正在从伴随对象中的XML解析数据,并将它们交给类的构造函数,如下所示:

class ArtistProfile (
                      name: String,
                      musicBrainzId: String,
                      url: String,
                      images: List[Image],
                      streamable: Boolean,
                      listeners: Int,
                      plays: Int,
                      similarArtists:List[SimpleArtist]) 

object ArtistProfile {

def apply(xml: NodeSeq) : ArtistProfile = {
  val root = xml
  val name = SimpleArtist.extractName(root);
  val url = SimpleArtist.extractUrl(root);

  val musicBrainzId = root \ "musicBrainzId" text
  val images:List[Image] = Image.findAllIn(root)
  val streamable = (root \ "streamable" text) eq ("1")

  val listeners = (root \ "stats" \ "listeners").text.toInt
  val plays = (root \ "stats" \ "plays").text.toInt

  new ArtistProfile(
    name,
    url,
    musicBrainzId,
    images,
    streamable,
    listeners,
    plays,
    SimpleArtist.findAllIn(xml \ "similar"))
  }
}

如您所见,这些是很多参数。我的问题是,将xml NodeSeq传递给ArtistProfile构造函数是否是一种更好的样式(就scala的功能而言),因此类本身接管解析而不是伴随对象。

我问这个是因为我正在尝试编写自己的last.fm scala库(作为scala的入门项目),我希望所有对象都能保持一致。

  1. 呼叫中有一些数据可能并不是每个人都需要的。使用第二种方法,如果对象列表变大则我可以使用惰性值,否则使用正常值。对于程序员来说,这不会有什么不同。
  2. 另一方面,解析创建对象所需的数据现在与对象本身分开(如上例所示)
  3. 哪种方法可以更好地解决问题?

1 个答案:

答案 0 :(得分:4)

我不确定是否有这样的黑白答案。您可以在类中放置辅助构造函数,以便您也可以从xml节点创建实例,而无需伴随对象。

然而,有充分的理由支持工厂模式。

  1. ArtistProfile类可以在不影响用户代码的情况下进行更改,无论是在其字段中还是在一个全新的子类中
  2. 在构造函数中进行实质性处理并不是一个好主意,因为JVM没有优化它
  3. 您可以缓存值而不是返回新实例,例如,如果请求两次相同的配置文件
  4. 从OO的角度来看,构造函数没有多大意义:对象如何构建自己?
  5. 它遵循Scala集合和案例类的惯例,并且更简洁地调用
  6. 工厂模式的主要缺点(假设您将主构造函数设为私有),如 Effective Java 中所述,是用户无法创建子类。

    我会将它们全部放在伴侣对象中。