vendredi 2 novembre 2012

Smarter pojo

Je vous ai montré, dans un article précédent, comment écrire un pojo immuable fournissant une API d'instanciation sémantique. Dans ce premier article sur Scala, je vais montrer comment faire de même et ceci beaucoup plus simplement, grâce aux concepts et aux différents sucres syntaxiques fournit par le langage.


En scala on définit une classe ainsi que son constructeur associé comme ceci :

class MyClass( myStringField: String, state: Boolean )
Mais par défaut les paramètres du constructeur sont privés et non accessible une fois la classe instanciée. Il suffit de déclarer les paramètres du constructeur de MyCLass en val pour qu'on puisse accéder à ces paramètres :

class MyClass( val myStringField: String, val state: Boolean )
Mais Scala fournit une structure de données spécifique pour gérer les simple classe avec getter : les case class

case class MyClass( myStringField: String, state: Boolean )
Avec cette notation, nous avons à notre disposition une classe immuable :

// notez qu'on n'utilise pas l'opérateur 'new' pour instancier une case class
val myClass = MyClass( "myString", true )
val myString = myClass.myStringField  // retourne "myString"
Les case class ne sont pas qu'un sucre syntaxique. Ce concept est au coeur du langage Scala, permettant une décomposition grâce au pattern matching par exemple, mais nous verrons cela dans un prochain article.

Si nous reprenons l'exemple de l'article smart pojo, en java, nous avions vu le cas de la gestion d'un attribut muable dans la classe, avec l'exemple du type Date. Scala promeut l'immuabilité, et il est fortement déconseillé d'utiliser des types muables dans son code, ceci étant facilité par la syntaxe et une API de base immuable. On préférera donc utiliser DateTime de jodatime (type immuable) plutôt que Date de Java par exemple.

Nous reste à traiter le besoin d'une API d'instantiation sémantique.
Encore une fois, Scala fournit un sucre syntaxique permettant de le faire simplement.

case class MyClass( myStringField: String, state: Boolean )
val myInstance = MyClass( myStringField = "string", state = true )
Tout ceci est bien sûr statiquement typé.
Voilà comment, en Scala, on peut, simplement et clairement, créée un Poso (Plain old Scala Object - cc @Miralak ;) ).
Cool non ? ;)

1 commentaire:

  1. Pour ceux qui veulent quand même utiliser un type muable dans leur case class, on peut s'en sortir en faisant un truc comme ca :
    case class MyClass( myStringField: String, state: Boolean, private val _date: Date ) {
    private val pDate = new Date( _date.getTime )
    def date: Date = pDate.clone()

    }

    RépondreSupprimer