2012-12-18 2 views
1

J'ai une classe qui représente les messages dans notre système. Où un message peut représenter une question, un document, une image, etc. Il existe environ 7 types différents d'objets que la classe Post peut représenter. Chacun des 7 différents types d'objets que nous avons a sa propre classe de métadonnées pour stocker des informations spécifiques aux objets supplémentaires.Classes Scala avec attribut de type arbitraire

Actuellement, ma classe Post a 7 attributs optionnels, dont l'un est rempli en fonction du type d'objet. Mais puisque la classe Post n'aura qu'un seul de ces 7 attributs, est-il possible de les consolider en un seul attribut avec un type arbitraire? Ensuite, je pourrais utiliser une déclaration de cas de match pour générer l'objet de métadonnées correct à l'exécution. Ou cet impossible avec Scala compte tenu de la nature fortement typée de la langue.

code

est ci-dessous:

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) 
     ) 
     } 
    } 
+0

L'utilisation d'une chaîne pour représenter le type semble être une mauvaise idée. Pourquoi ne pas avoir plusieurs types d'implémenter une interface Post commune, comme ça? 'trait Post { def id: Long def nom: String } classe de cas FilePost (id: Long, nom: String, info: FileInfo) extends Post {}' – user1727289

Répondre

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) 
} 
1

Pourquoi ne pas faire abstraction après, puis mettre en œuvre une sous-classe pour chaque type de poste? Quelque chose comme:

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 => ... 
    } 

Doh! - ressemble à une réponse précédente a dit la même chose ...

Questions connexes