Coding Stories
Singe savant en ingénierie logicielle
Singe savant en ingénierie logicielle
2/09/10
Après avoir vu cette question sur stackoverflow j’ai pensé que présenter la façon dont je gère la signature de code avec maven pouvait en intéresser certains.
24/08/10
java.lang.reflect.Proxy qui a été ajouté dans la bibliothèque standard à partir de Java 1.3 est un de mes jouets préférés. Cette classe permet de créer dynamiquement des instances qui implémentent n’importe quelle liste d’interfaces.
Prenons un exemple :
public interface UserAccount { Credentials getCredentials(); void updateCredentials(Credentials credentials); void suspend(); void resume(); }
14/07/10
Il aura fallu attendre sept release candidates, 3 mois depuis la sortie de la RC1 et presque 6 mois depuis la première beta, mais la version finale 2.8.0 du langage Scala est finalement disponible au téléchargement.
Heureusement pour nous remercier de notre patiente les nouveautés sont nombreuses : meilleure API pour les collections, amélioration du support des annotations, amélioration de la bibliothèque XML, spécialisation des types, ajout d’un décompilateur, l’outil scaladoc en version 2…
Pour voir la liste complète des améliorations, nouveautés et corrections ou télécharger c’est ici : http://www.scala-lang.org/node/7009
7/07/10
La conférence Annotations Java animée par Olivier Croisier, expert java et auteur du blog The Coders Breakfast, s’est tenue le 29 juin dernier a eu lieu la dans les locaux de Zénika.
Les annotations, je pensais bien connaitre… J’avais tort.
Après s’être présenté et avoir présenté Zénika, Olivier commence par un rappel historique : en matière de méta-programmation, il existait déjà l’API Doclets qui permet d’ajouter ses propres tags dans les commentaires du code. Les développeurs ont vite détourné cette fonctionnalité, souvent pour permettre la génération automatique de code. A partir de Java 5 sont apparues les annotations.
Dans la bibliothèque Java standard on trouve finalement assez peu d’annotations : @Override, @SuppressWarnings et @Deprecated ainsi que quelques unes dans le package java.lang.annotation (des meta-annotations, c’est à dire des annotations que l’on place sur d’autres annotations comme Target ou Retention). Avec Java 6, on en voit arriver d’autres dans les packages javax.annotation ou javax.xml.bind.annotation. Mais ce sont surtout les frameworks et autres Standards qui font la part belle aux annotations : Hibernate, JPA, JDO, Spring, Guice, J2EE6… Le plus souvent il s’agit de remplacer de longs fichiers de description en XML.
26/06/10
Nouvelle mise à jour bimensuelle de la part de Google concernant la répartition des différentes versions d’android :
Cette fois, c’est fait, android 2.1 passe la barre des 50%. Toutefois il faudra compter avec le déploiement d’android 2.2, aka Froyo, dans les prochains mois (si ce n’est les prochaines semaines).
Et pendant ce temps les possesseurs du HTC Hero (dont fait partie votre serviteur) attendent avec une impatience non feinte la mise à jour vers la version 2.1. Elle a été promise, annoncée de nombreuses fois et reportée tout autant… Elle est maintenant prévue pour le 29 juin. J’attends…
9/06/10
J’ai procédé à la release de la bibliothèque jsChessboard en version 0.2. jsChessboard est une bibliothèque qui permet d’interpréter des parties d’échecs et de dessiner des échiquiers, le tout entièrement en javascript en utilisant le tag <canvas>.
Les objectifs fixés pour la version 0.3 :
Le site du projet : http://jschessboard.com
Pour voir la bibliothèque en action, il y quelques démos sur le site du projet ici, là ou encore là.
31/05/10
Quand je coiffe ma casquette de release manager je dois m’assurer que le logiciel que je prépare à affubler d’un joli numéro de version est prêt. Le code n’est pas tout ; il existe une multitude de petits détails à vérifier pour satisfaire les critères de qualité demandés : les tests (unitaires, d’intégration) passent ils ? Le coding style a-t-il été bien respecté ? Les dépendences sont-elles à jour ? Je me suis donc fait une release checklist qui détaille point par point toutes ces tâches.
20/05/10
Le crible d’Ératosthène est un grand classique des langages fonctionnels :
def primes (end: Int): Seq[Int] = { def sieve (list: Seq[Int]): Seq[Int] = { list match { case Nil => List() case x :: xs => List(x) ++ sieve(xs.filter(_ % x != 0)) } } sieve(List.range(2, end)) }
Faisons un test :
scala> primes(100) res0: Seq[Int] = List(2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97)
19/05/10
Google vient de mettre à jour ses données concernant la répartition des différentes versions d’android :
Ces chiffres ont été collectés à partir des statistiques de connexion à l’Android Market. Voilà ce que cela donne :
| Android Platform | Percent of Devices |
|---|---|
| Android 1.1 | 0.1% |
| Android 1.5 | 34.1% |
| Android 1.6 | 28.0% |
| Android 2.0 | 0.2% |
| Android 2.0.1 | 0.4% |
| Android 2.1 | 37.2% |
C’est en comparant avec les même données du mois dernier que cela devient intéressant : Android 2.1 passe de 27,3% à 37,2% de part de marché, soit une augmentation de presque 10%. À l’opposé, les versions 1.5 et 1.6 perdent respectivement 3,8% et 3,6%. Cela veut surtout dire que la version 2.1 est désormais la version majoritairement déployée sur l’ensemble des terminaux Android.
En supposant que ces chiffres soit représentatifs du parc (et SOS Android a fait quelques comparaisons et semble le croire), on assiste, lentement mais sûrement, à une concentration des versions diffusées. Les améliorations entre 1.x et les 2.x ayant réellement amélioré la qualité de l’OS, cette concentration est plutôt une bonne nouvelle.
À moins que la version 2.2, alias Froyo, ne vienne changer la donne.
Update :après plusieurs mois de rumeurs HTC vient de publier la première mise à jour officielle du Hero (Sprint only pour le moment)
17/05/10
Retour aux racines du génie logiciel : le tri. Tout développeur doit savoir écrire un tri en moins de 5 minutes.
Comment faire un quicksort en Scala ?
def sort (list : Seq[Int]) : Seq[Int] = { list match { case Nil => list case x :: xs => sort(xs.filter(_ < x)) ++ List(x) ++ sort(xs.filter(_ >= x)) } }
Ça marche pour les int. Mais si je veux trier des float, des String, des Scoubidou ? Il faudrait généraliser la fonction. Pour cela il existe le trait Ordered qui permet de définir une relation d’ordre total sur les éléments.
def sort [A <% Ordered[A]] (list:Seq[A]): Seq[A] = { list match { case Nil => list case x :: xs => sort(xs.filter(_ < x)) ++ List(x) ++ sort(xs.filter(_ >= x)) } }
L’expression [A <% Ordered[A]] est une view bound. Cela permet de définir une fonction polymorphique mais aussi fournit la conversion implicite du type A en Ordered[A]. En fait cette définition :
def sort [A <% Ordered[A]] (list:Seq[A]): Seq[A] = { /* ... */ }
est équivalente à :
def sort [A] (list:Seq[A])(implicit conv: A => Ordered[A]): Seq[A] = { /* ... */ }
Avantage : l’objet scala.Predef qui est tourjours chargé par Scala possède déjà plusieurs fonctions implicites de converstion par exemple Int vers Ordered[Int].
Et si maintenant nous compararions nos scoubidous ?
case class Scoubidou(name: String) val samy = Scoubidou("Samy") val daphne = Scoubidou("Daphne") sort(List(samy, daphne)) > error: no implicit argument matching parameter type (Scoubidou) => Ordered[Scoubidou] was found.
Et oui, sort attend un Ordered. Bien sûr nous pourrions nous arranger pour que Scoubidou étende le trait Ordered mais parfois ce n’est simplement pas possible, par exemple parce que le type est fournit par une bibliothèque sur laquelle on n’a pas la main. Mais il est possible de définir une fonction implicite de conversion qui trie les Scoubidou selon l’ordre lexicographique (en clair on va déléguer l’appel à compare au champ name)
implicit def scoubidou2ordered (x: Scoubidou): Ordered[Scoubidou] = { new Ordered[Scoubidou] { def compare(that: Scoubidou): Int = { x.name.compare(that.name) } } }
et maintenant on peut trier la liste :
sort(List(samy, daphne)) > Seq[Scoubidou] = List(Scoubidou(Daphne), Scoubidou(Samy))