Recherche

Coder's IO

Tag

API

Typeof

 

Typeof est l'API qui a été développée avec pour objectif d’éliminer (ou de limiter) l’utilisation de l’opérateur instanceof et du downcasting
Il est bien connu que l’usage de cet opérateur relève d’une mauvaise pratique tout comme le principe de downcasting. 

Cette API a été développée à l’origine dans le cadre d’un projet afin de limiter l’utilisation des deux éléments décriés ci-dessus.
L’auteur, +Tomasz Nurkiewicz , a implémenté cette API sous forme d’un DSL. 
Les propriétés mises en avant sont :

– plus de downcasting explicite,
– limitation de l’utilisation de l’opérateur instanceof,
– une syntaxe plus claire et facile à utiliser,
– utilisation du typage fort de Java,
– permet de travailler avec tout type de classe.

Voici un exemple de la syntaxe  : 

int result = whenTypeOf(obj).
   is(String.class).thenReturn(String::length).
   is(Date.class).thenReturn(d -> (int) d.getTime()).
   is(Number.class).thenReturn(Number::intValue).
   is(TimeZone.class).thenReturn(tz -> tz.getRawOffset() / 1000).
   is(MyType.class).thenReturn(7).
   get();

Pour les Javaistes/Scalaistes, on retrouve des bribes du pattern matching .

Un des avantages du DSL est de prévenir de toute utilisation incorrecte au moment de la compilation (gain de temps). Vous pourrez trouver des exemples sur le lien attaché à ce post ainsi que des détails sur l’implémentation de typeof.

Les sources, très légères (peu de classes) sont disponibles sur github.

#java #instanceOf #DSL #API

Javolution

Certains domaines fonctionnels nécessitent d'avoir du traitement en temps réel, comme le domaine bancaire, le domaine du jeu, l'aviation, etc.

On peut retrouver dans tous ces domaines le langage Java. Malheureusement, il souffre de certains maux qui ont un impact directement sur les temps de réponse.
Bien entendu, ces problématiques de temps de réponse sont vraiment liés à ces domaines fonctionnels très exigeants.

L'origine de ces problèmes est liée en général aux points suivants :

– Garbage collector, lorsqu'il "stoppe le monde" ,
– des temps de réponse liés au JIT,
– l'initialisation des classes,
– dans le cadre des collections, le redimensionnement interne.
– etc

Je le répète, les points soulevés ci-dessus sont critiques dans certains domaines fonctionnels exigeants.

Face à ces problématiques, IBM et Sun ont développé respectivement IBM Websphere Real Time et Sun Mackinac. Ces deux solutions sont payantes. En face, Jean-Marie Dautelle a développé une librairie gratuite nommée : Javolution.

L'objectif de cette librairie est de permettre des temps d'exécution beaucoup plus rapides et prévisibles.
Les points suivants vous donnent une idée des possibilités de Javolution.

Elle permet :
– d'exploiter plusieurs coeurs sur un processeur.
– de réduire les temps d'exécution à l'aide d'un jeu d'annotations
– l'intégration native avec un écosystème OSGi.
– collections : support de Map-Reduce, parallélisme, views (~Stream dans Java8).
– manipulation des collections.
– etc…

Cette liste n'est pas exhaustive. L'ensemble des fonctionnalités est décrit dans le lien attaché à ce post.

Il est intéressant de souligner la légèreté du jar de la librairie : ~400Ko
Javolution supporte Maven, et est disponible sur les repositories publiques.

L'ayant découvert que très récemment au travers d'une discussion technique, Je n'ai pas eu le temps de la mettre en oeuvre. je vous recommande de parcourir le site ainsi que l'ensemble des liens disponibles sur le site attaché à l'article.

#java #real #time #api

Classe utilitaire ou pas ?

L’article que je vous propose aujourd’hui est un petit état des lieux sur l’intérêt des classes utilitaires dans nos projets.
Il n’est pas rare, voir même courant, de trouver dans les projets sur lesquels nous développons, tout un tas de classes utilitaires adressant, en règle générale, les problématiques suivantes :

– Conversion de date
– Manipulation de chaine de caractères
– Vérification de la nullité ou non d’une référence d’un objet
– Traitement sur des collections
– etc

Le nommage des classes est souvent suffixé par les termes suivants :

– Util(s)
– Tool(s)

et se trouve dans le meilleur des cas dans des packages nommés de la façon suivante :

– **.**.**.utils
– **.**.**.tools

Le nom des packages peut varier selon si les classes utilitaires sont liées à un contexte fonctionnel.
Généralement, ces classes sont composées de plusieurs méthodes traitant sensiblement un contexte commun (manipulation de chaine).

Le pour : Ce que ces classes peuvent nous apporter
Elles ont vocation à factoriser un algorithme ou un traitement générique, que d’autres pourront réutiliser à volonté.
La démarche est intéressante en terme de coût de conception, de maintenance, de gain de temps.
Même si ces arguments sont tout à fait valables et incontournables dans le paradigme objet nous allons voir dans la section suivante des contre-exemples mettant en cause ce type de classe.

Le contre : Ce qu’elles peuvent générer
Dans cette section, je vais noircir le tableau en listant les points négatifs concernant l’existence de telles classes au sein de nos projets.

1 – La confusion
Au début, une classe utilitaire à un sens précis et adresse un domaine spécifique.
Avec le temps, le domaine adressé peut dévier et la classe se voit enrichie de méthodes sortant du périmètre initial et peu à peu cela devient une classe fourre-tout. La sémantique exprimée par le nom de la classe se perdra doucement.
A contrario, les classes utilitaires peuvent pulluler sur le projet et l’on se retrouvera avec du code dupliqué.

2 – Tests unitaires supplémentaires
Une bonne couverture de code est essentielle dans un projet. Ceci implique qu’il faudra créer l’ensemble des tests unitaires pour cette partie du code. Bien que la démarche soit bonne, cela aura pour conséquence d’allonger un peu plus le temps de build de notre application. Ce qui n’est pas une bonne chose…

_3 – Documentation pauvre = Redondance _
La documentation : le parent pauvre d’un projet informatique.
Lorsque l’on est en train de développer une fonctionnalité et que l’on a besoin de savoir si un utilitaire est disponible (par exemple : transformer une liste de String en une chaine de caractère contenant l’ensemble des occurrences de la liste séparées par une virgule), on commence à rechercher dans le code puis on tente de voir dans la documentation projet si une telle classe existe. Après une recherche infructueuse, on finit par la développer soit-même.
En fait, un mois plutôt, votre collègue, qui est parti depuis, l’avait déjà fait mais pour une autre fonctionnalité (il avait nommé la classe en la préfixant par le nom de la fonctionnalité et en la suffixant de Tools).
Conclusion, l’utilitaire a été développé deux fois selon deux approches différentes => nous avons de la redondance.

4 – Et les libs disponibles
Il y a quelques années, au début de Java, le nombre de libs était limité. Aujourd’hui, il est difficile de ne pas trouver une librairie adressant les problématiques récurrentes de nos projets. Avec les moyens de recherche à disposition, il est plus facile de trouver sur internet une lib répondant à notre besoin, plutôt que de retrouver vainement du code dans l’application.
De plus, le code de ces libs est éprouvé et plus sûr.
Ci-dessous, quelques librairies adressant les problèmes les plus courants :

– Google Guava
– Commons Jakarta
– Joda
– etc.

5 – PermGen
Une problématique plus bas niveau concerne la taille de la zone mémoire PermGen.
Cette zone stocke l’ensemble des fichiers .class du projet.
Dans un projet classique géré par Maven, un certain nombre de dépendances (transitives) sont ajoutées au projet. Bien souvent, les libs évoquées ci-dessus sont incluses donc disponibles.
Le fait d’ajouter des classes utilitaires dans le projet ne fait qu’augmenter l’espace occupé dans la zone mémoire PermGen. Réduire le recours à des classes utilitaires permet de ne pas charger un peu plus cette zone de la JVM. Je conviens que cet argument est à relativiser.

Mais doit-on renoncer aux classes utilitaires dans les projets ?
Je pense que la réponse n’est pas aussi catégorique que ça.

– Les classes utilitaires doivent être utilisées dans des cas précis pour adresser des problématiques purement fonctionnelles. Par exemple, la transformation d’un objet métier (issue du domaine), la réalisation d’un calcul lié au métier du projet, etc. Dans ces cas, aucune librairie ne saura répondre à votre problème vraiment spécifique au métier sous-jacent.
– Il peut arriver, malgré tout l’écosystème à disposition, que l’on ne trouve pas chaussure à son pied.

Même si ces cas existent, je reste persuadé que dans 90% des cas, on trouve ce que l’on cherche.

Trop de librairies tue la librairie
Maintenant on peut prendre le problème à l’envers et se trouver confronté à plusieurs librairies répondant à mon problème.
Pour départager les finalistes, il faut regarder plusieurs critères :
– âge de la librairie : détermine sa pérennité
– la documentation : la facilité pour la prise en main
– l’activité sur le projet : si des bugs sont détectés, seront-ils corrigés ?

En conclusion, je pense qu’il est important de bien connaitre l’écosystème dans lequel nous évoluons. D’avoir une bonne connaissance des outils existants afin de les exploiter et ne pas réinventer la roue.
Aussi de savoir limiter son esprit créatif et de chercher au lieu de réinventer.
En adoptant cette démarche, nous garderons aussi toute notre énergie pour se concentrer sur le code métier.

N’hésitez pas à réagir dans les commentaires, dans un sens ou dans l’autre, afin d’enrichir le contenu de cet article par diverses expériences.

#java #utilitaire #tool #api

Créez un site Web ou un blog gratuitement sur WordPress.com.

Retour en haut ↑

Concevoir un site comme celui-ci avec WordPress.com
Commencer