我想改进以下与Cassandra相关的Scala代码。我有两个不相关的user defined types,它们实际上是在Java源文件中(省略了详细信息)。
public class Blob { .. }
public class Meta { .. }
以下是我目前使用Scala的方法:
private val blobMapper: Mapper[Blob] = mappingManager.mapper(classOf[Blob])
private val metaMapper: Mapper[Meta] = mappingManager.mapper(classOf[Meta])
def save(entity: Object) = {
entity match {
case blob: Blob => blobMapper.saveAsync(blob)
case meta: Meta => metaMapper.saveAsync(meta)
case _ => // exception
}
}
虽然这有效,但如何避免以下问题
Blob
或Meta
save
Object
作为参数类型答案 0 :(得分:5)
您绝对可以使用Mapper
作为类型类,执行:
def save[A](entity: A)(implicit mapper: Mapper[A]) = mapper.saveAsync(entity)
现在,您有一个通用方法,可以对A
范围内的每个Mapper[A]
类型执行保存操作。
此外,可能会改进mappingManager.mapper
实现以避免classOf
,但很难从当前状态的问题中看出来。
答案 1 :(得分:1)
几个问题:
mappingManager.mapper(cls)
贵吗? 这样的事情能为你效劳吗?
def save[T: Manifest](entity: T) = {
mappingManager.mapper(manifest[T].runtimeClass).saveAsync(entity)
}
如果您确实关心确保Meta的子类获取正确的映射器,那么您可能会在isAssignableFrom
中找到.mapper
有用(并在HashMap中存储找到的子类,因此您只需要看一次)。
编辑:那么也许你想要这样的东西(忽略线程问题):
private[this] val mapperMap = mutable.HashMap[Class[_], Mapper[_]]()
def save[T: Manifest](entity: T) = {
val cls = manifest[T].runtimeClass
mapperMap.getOrElseUpdate(cls, mappingManager.mapper(cls))
.asInstanceOf[Mapper[T]]
.saveAsync(entity)
}