代码之家  ›  专栏  ›  技术社区  ›  Vlad Gudim nuriaion

要在业务模型中使用的scala集实现?

  •  1
  • Vlad Gudim nuriaion  · 技术社区  · 14 年前

    假设我们想要建立一个大的社交网络(因为社交网络现在都很流行)。我们将从一个简单的前提开始,即任何想使用我们的社交网络的人都应该能够以他们的名义注册,然后成为朋友或与其他与我们注册的人发生关系:

    import scala.collection._
    
    class Person (var name: String) {
        private val _friends = new mutable.HashSet[Person]
    
        def befriends     (p: Person) { _friends+=p }
        def fallsOutWith  (p: Person) { _friends-=p }
        def friends () = _friends toSet
        override def toString = name
    }
    

    到现在为止,一直都还不错:

    val brad     = new Person("Brad Pitt")
    val angelina = new Person("Angelina Jolie")
    
    brad befriends angelina
    angelina befriends brad 
    

    好东西!最后,让我们看看布拉德所有朋友的名单:

    brad.friends.foreach(println)
    

    它起作用了,我们将用我们完美的社交网络,即100%的scala,来席卷世界!

    现在来谈谈无聊的技术性话题。我们需要能够持久化数据,db4o似乎是一个不错的选择,还有一些代码:

     db store brad // job done!
    

    然后从硬盘恢复Brad:

     val q = db.query       
     q.constrain(classOf[Person])
     q.descend("name").constrain("Brad Pitt")           
     val brad = q.execute.get(0)                
    

    再次查看朋友列表…

     brad.friends.foreach(println)
    

    砰! 空指针异常 !经过一点调试,结果发现我们用来跟踪朋友的mutable.hashset的底层数据存储被定义为 瞬态 在里面 scala.collection.mutable.flathashtable :

    @transient protected var table: Array[AnyRef] = new Array(initialCapacity) 
    

    因此,当我们告诉db4o存储一个人时,实际的朋友列表没有连续化。似乎db4o应该使用 读取对象 写入对象 而不是哈希集的方法。

    我想知道是否有方法可以告诉db4o正确地序列化/反序列化哈希集,或者是否有更合适的、db4o友好的scala集实现?

    2 回复  |  直到 14 年前
        1
  •  2
  •   Kevin Wright    14 年前

    您需要使用db4o有什么特别的原因吗?与许多Java持久性框架一样,它假设对象中的可变形性是好的,这与idiomatic Scala没有太好的配合。

    使用Squeryl或Akka能够处理的多个NoSQL商店之一,您可能会有更多的乐趣。如果没有进一步的信息,我可能会推荐斯奎尔。

    这样做之后,您还需要避免在您的个人对象中保持双向的朋友关系——它们将使不可变的“更新”几乎不可能。将此信息提升到专用的 Relationship 对象将有很大帮助,它还允许您随着系统的发展轻松地添加有关关系性质的更多信息。

    你最初的问题就变得无关紧要了。)

        2
  •  0
  •   Vlad Gudim nuriaion    14 年前

    scala.collection.immutable.hashset不存在相同的序列化问题,重新编写依赖于不可变哈希集的Person类可以解决此问题:

    import scala.collection._ 
    
    class Person (var name: String) { 
        private var _friends = new immutable.HashSet[Person] 
    
        def befriends     (p: Person) { _friends=_friends+p } 
        def fallsOutWith  (p: Person) { _friends=_friends-p } 
        def friends () = _friends
        override def toString = name 
    }