1

我有一个类代表我们系统中的帖子。帖子可能代表问题、文档、图像等。 Post 类可以代表大约 7 种不同类型的对象。我们拥有的 7 种不同类型的对象中的每一种都有自己的元数据类来存储额外的对象特定信息。

目前,我的 Post 类有 7 个可选属性,其中一个根据对象的类型填充。但是由于 Post 类只会填充这 7 个属性中的一个,有没有办法将它们合并为具有任意类型的单个属性?然后我可以使用 match case 语句在运行时生成正确的元数据对象。或者考虑到语言的强类型特性,这在 Scala 中是不可能的。

代码如下:

    case class Post (
      id       : Long,
      typ      : String,
      name     : String,
      fileInfo : Option[FileInfo],
      imageInfo : Option[FileImageInfo],
      videoInfo : Option[FileVideoInfo],
      audioInfo : Option[FileAudioInfo],
      eventInfo: Option[EventInfo],
      lectureInfo: Option[LectureInfo],
      drawingInfo: Option[DrawingInfo]
    )


    object Post {

      val simple = {
        get[Long]("object_view.id") ~
        get[String]("object_view.type") ~
        get[String]("object_view.name") map {
          case id~typ~name =>
            Post(
                 id, 
                 typ, 
                 name, 
                 FileInfo.getById(id),
                 FileImageInfo.getById(id),
                 FileVideoInfo.getById(id),
                 FileAudioInfo.getById(id),
                 EventInfo.getFirst(id),
                 LectureInfo.getById(id),
                 DrawingInfo.getById(id)
          )
       }
    }
4

2 回答 2

1

为什么不将 Post 抽象化,然后为每种不同类型的 post 实现一个子类?就像是:

  abstract class Post { val id:Long; val typ:String; val name:String; }
  case class FilePost(
      id       : Long,
      typ      : String,
      name     : String,
      fileInfo : Option[FileInfo
  );
  case class ImagePost(
      id       : Long,
      typ      : String,
      name     : String,
      imageInfo : FileImageInfo
  );
  ...

  def doSomething( post:Post ):Unit = post match {
      case fp:FilePost => ...
    }

嗬!- 看起来早先的回应说同样的话......

于 2012-12-18T19:23:10.847 回答
0
class FileInfo(val name: String)
abstract trait CanGet[T] { val value: Option[T]; def get = value.get }
case class PostFileInfo(val id: Long, val typ: String, val name: String) extends 
  { val value = Some(new FileInfo(name)) } with CanGet[FileInfo]

...

(1L, "FileInfo", "FileName") match { 
  case (id, typ @ "FileInfo", name) => new PostFileInfo(1, typ, name)
}
于 2012-12-18T02:22:59.330 回答