Scala: Quelques points forts

ScalaJe compte faire une série de billets pour présenter Scala, mais ce billet est plutot une sorte de teaser, qui présente quelque unes des constructions Scala qui m’ont impressionné jusque là.

Les exemples présetns ici ne seront donc pas bien documentés ou expliqués, mais ils serviront juste à montrer la puissance du langage Scala.

Je vais présenter les singletons, l’AOP et le lazy fetch.

Singletons:

Scala offre ni plus ni moins qu’un support en natif des singletons, evitant ainsi d’avoir à coder la chose à la main, des choses du genre:

Java

public class SingletonFacory {	
		private static Object singleton;	
	
		public synchronized static Object getSingleton() {	
				if (singleton == null) {	
						singleton = new Object();	
				}	
				return singleton;	
		}	
}

Ou encore passer par un conteneur comme Spring.

Ce que ça donne en Scala ?

Rien en particulier, suffit de déclare l’objet en question comme object au lieu de class, ce qui donne:

object TheSingleton {
//les champs 	
}

C’est tout !
Suffit d’y accéder par son nom, n’importe où dans l’application, et on est sur d’avoir la même instance partout.

AOP

Scala offre en natif une notion très proche de l’AOP, qui est les traits.
Prenons les traits suivant:

trait Action {	
	       def doAction	
}	
	
trait LogAction extends Action{	
	 abstract override def doAction = {	
	   println("Before Action")	
	   super.doAction 	
	   println("End Action")	
	 }	
}	
	
trait RetryAction extends Action{	
	 abstract override def doAction = {	
	   println("Try Action")	
	   try{	
	     super.doAction	
	     println("End Try Action")	
	   } catch {	
	     case e: Error => {	
	       try{	
	       println("Retry Action")        	
	       super.doAction	
	       println("End Retry Action")	
	       } catch {	
	       case e: Error => println("Failed retry")	
	       }	
	     }	
	   } 	
	 }	
}

Les traits sont une sorte d’interfaces à la Java mais qui peuvent contenuir des implémnetations (c’est pas de l’héritage multiple rassurez vous, c’est les mixins, mais j’y reviendrais dans un autre billet).
En gros, j’ai défini un tait Action qui déclare la méthode doAction ainsi que deux traits (LogAction et RetryAction) qui implémentent Action, le premier affiche des messages avant et après avoir invoqué la méthode doAction du parent, et le second invoque doAction du parent, et si ça echoue (lance une exception), relance une deuxième fois la méthode)

Maintenat, disons que l’on dispose d’une cette implémentation de Action :

class TestAction extends Action{	
	       def doAction = {	
	   println("Real Action")	
	   if(List(1, 2).size==2)	
	     error("Stupid error");	
	 }	
}

Cette action ne fait qu’afficher un message et lancer une exception.

val action = new TestAction() with LogAction with RetryAction
action.doAction

En gros, on instancie une action avec le LogAction et RetryAction comme traits associés (with). a l’exécution, ça donne:

Try Action <-Aspect retry
Before Action <-Aspect log
Real Action <-Action réelle
Retry Action <-Aspect retry
Before Action <-Aspect log
Real Action <-Action réelle
Failed retry <-Aspect retry

Wow ! Sans Spring, sans AspectJ, sans reflection, sans weaving, sans rien ! Juste le langage Scala !

Lazy Fetch

Je passe maitnenant à une autre fonctionnalité Scala: le chargement déféré (lazy), une fonctionnalité très prisé par les ORMs (Hibernate, etc.).
L’implémenter en Java nécessite de passer par une bibliothèque de reflection (cglib, javassist, etc.) et le passage par des proxies.

En Scala, ça revient à ajouter le mot lazy à la défnition du champ.
Par exemple, si on a deux classes Person et School:

classe School: un simple POSO (POJO, mais à la sauce Scala)

case class School(id: Int, name: String)

Et un DAO ficitif :

object SchoolDb {	
	 private val schools = List(School(1, "ensi"), School(2, "ipest"))	
	 	
	 def school(id: Int) = {	
	   println("getSchool")	
	   schools.find(p=>p.id==id).get	
	 }	
}

Ne faites pas attention aux détails (closures, liste, etc.).
en gros, etant donné un identifiant, la méthode school retourne l’objet School qui a cet identifiant, mais aussi affiche un message getSchool.

Voici maintenant person:

case class Person(id: Int, name: String, schoolId: Int){	
	 lazy val school : School = SchoolDb.school(schoolId)	
}[/sourcecode language]

<p>Remarquez le lazy avant le chmp school ainsi que l'appele à la methode SchoolDb.school</p>
val p = Person(1, "djo", 2);	
	   println("...")	
	   println(p.school)	
	   println(p.school)

Ce qui affiche à la console:

… <-méthode SchoolDb.school non appelée jusque là
getSchool <- méthode SchoolDb.school appelé suite au premier accès au champ person.school
School(2,ipest) <- affichage du champ person.school
School(2,ipest) <- affichage du champ person.school mais sans appel de SchoolDb.school

Voilou !
Je posterais plus tard un autr billet montrant une autre fonctionnalité super-puissante de Scala qui est le pattern-matching.

Advertisements

4 Responses to Scala: Quelques points forts

  1. Bonjour Jawher,

    Très bon billet. Je découvre même que tu avais posté cela sur Developpez.com !!!

    Il y a une question qui me vient en lisant ton billet c’est sur l’intégration de Scala dans Java. Scala est-il un remplaçant de Java ? Scala s’utilise-t-il tout seul ? Comment mixer codes Java et Scala ? En fait, mes questions me permettront de savoir si les choses que tu viens de présenter pourraient s’intégrer dans mes codes existants.

    Peut-être que j’anticipe ta série de billets avec ce types de questions …

    Mickael

  2. jawher says:

    Bonsoir Mickael,

    BARON Mickael :

    Très bon billet.

    Merci !

    BARON Mickael :

    Je découvre même que tu avais posté cela sur Developpez.com !!!

    Yep, et y’a maintenant exactement une année moins 2 jours 😀

    BARON Mickael :

    Il y a une question qui me vient en lisant ton billet c’est sur l’intégration de Scala dans Java. Scala est-il un remplaçant de Java ?

    Oui, Scala est un langage à part entière, avec son propre compilateur et même son propre évaluateur. Par contre, comme ça compile vers du bytecode, tu peux aussi exécuter un programme Scala avec la commande “java”, moyennant l’inclusion de scala-library.jar.

    BARON Mickael :

    Comment mixer codes Java et Scala ?

    Hum, jamais testé la chose moi moi mais théoriquement c’est possible avec maven par exemple. J’ai lu quelque part qu’on (Odersky et co) avait travaillé sur ça dans le compilateur Scala, mais j’ai pas plus de détails sur le sujet pour le moment.

    BARON Mickael :

    En fait, mes questions me permettront de savoir si les choses que tu viens de présenter pourraient s’intégrer dans mes codes existants.

    Un truc qui marchera pour sûr sera de passer par des modules maven.

    BARON Mickael :

    Peut-être que j’anticipe ta série de billets avec ce types de questions …

    J’espère retrouver bientôt le temps et la volonté pour blogger plus fréquemment de nouveau.

    Entre temps, tu peux jeter un coup d’oeil sur ce que j’avais déjà publié sur Scala (a prendre avec pincettes, vu que j’ai écrit ça au fûr et à mesure de mon apprentissage de ce langage): https://jawher.wordpress.com/category/scala/.

    Cordialement,
    Jawher

  3. Merci pour ces réponses.

    Pour information, Nicolas Martignole “blogue” en ce moment sur Scala (http://www.touilleur-express.fr/2010/03/23/scala-son-histoire/)

    Il faut que j’essaye Scala pour me faire une idée précise …

    Mickael

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: