lundi 28 janvier 2013

5 Bonnes raisons du MDA pour le développement mobile

 
Article co-écrit par Florent Dupont et Lamia Gaouar, qui prépare actuellement un doctorat SIC autour des développements Android et MDA à l'université de Tlemcen.

La démocratisation des plateformes nomades (mobiles et tablettes) poussent les entreprises à proposer toujours plus de services aux utilisateurs. Elles ont, en effet, bien compris tous les enjeux qui se trament derrière les applications mobile : communication améliorée, nouveaux services aux utilisateurs, régie publicitaire, avantage concurrentiel, etc.

Cet engouement pour les plateformes nomades offre de nouvelles perspectives de marché, notamment pour les entreprises éditrices (que ce soient des Mobile Agencies, des Web Agencies ou encore des SSII) qui peuvent proposer leur expertise de développement. Depuis 2011, le marché des ventes de mobile dépasse les ventes de PC et offre donc des perspectives de marché de développement d’applications mobile très importantes.

Ces éditeurs doivent cependant s’adapter aux plateformes de développement mobile qui sont foncièrement différentes de celle des applications Desktop. En effet, ces plateformes imposent des contraintes fortes, les ressources étant limitées : taille d’écran réduite, processeur faible, stockage limité, connexion lente et intermittente, RAM limitée. Toutes ces limitations impliquent une discipline de développement particulière pour que l’expérience utilisateur soit toujours efficace.

Au niveau logiciel, de multiples OS (Android, iOS, BlackBerry, Windows Phone) se disputent le marché de la mobilité. A chaque OS correspond une plateforme de téléchargement d’applications, des outils de développement et un langage de programmation permettant le développement et la distribution des applications :

 


Cette hétérogénéité des outils de développement et des langages, rend difficile le développement d’applications mobile multiplateformes. Elle pousse les développeurs à faire un choix sur la plateforme, tout en assurant la plus grande distribution possible.

Des outils pour aider les développeurs ?

Google a récemment apporté un élément de réponse avec le projet J2ObjC qui permet de convertir du code Java (Android) en code Objective-C (iOS). L’intérêt d’une telle démarche est de pouvoir récupérer le code fonctionnel d’une application Android afin de faciliter la conversion vers la plateforme iOS.
Mais cette approche pose encore de nombreuses questions :
  • Qu’en est-il de la conversion Objective-C vers Java ? Et vers d’autres OS  ?
  • Et plus généralement, comment capitaliser sur le fonctionnel d’une application indépendamment des préoccupations techniques afin d’en faciliter la migration ?  

Une réponse avec le MDA

L’approche MDA a su faire ses preuves pour le développement d’applications d’entreprise et peut également apporter beaucoup pour les applications mobile. Au travers de 5 points, nous allons voir pourquoi et comment l’approche MDA peut nous aider à assurer la pérennité des savoir-faire, le gain de productivité tout en répondant aux problématiques de fragmentation des plateformes mobile.

1. Réduire les problématiques de fragmentation

Chaque OS mobile détient une part du marché, et donc chacun possède sa communauté d’utilisateurs et de développeurs. Cette fragmentation pose un souci pour les entreprises désireuses de toucher un large public car le développement des applications multiplateformes est très coûteux en temps et en argent. Les entreprises se trouvent face à un dilemme :
  • Développer une application de qualité en un temps efficace et limiter sa distribution à une plateforme spécifique. 
  • Développer une application aux fonctionnalités réduites, mais proposée sur plusieurs plateformes et à un large panel d'utilisateurs.
Des solutions hybrides existent comme Cordova (application native construite à partir de vue Web et Html5) ou Flex 4.6 (exécution sous plateforme Flash) et permettent d’assurer du multiplateformes, mais leur prise en charge reste techniquement partielle. En réalité, une application native restera plus adaptée pour plusieurs raisons :
  • L’utilisateur dispose d’un environnement adapté à sa plateforme et à ses spécificités : l’expérience utilisateur reste optimale.
  • Le développeur tire profit de l’architecture spécifique et optimise l’application en fonction de la plateforme.
  • L’application peut évoluer et éventuellement tirer parti des fonctionnalités spécifiques à une plateforme ou OS.

L’approche MDA peut répondre à ces problématiques : décrire les besoins fonctionnels d’une application indépendamment de la plateforme d’exécution, et respecter les spécificités techniques de chaque plateforme. MDA permet de générer le code sans valeur ajoutée (boilerplate code) spécifique à chaque plateforme. On assure ainsi un gain de productivité, même sur des applications natives.

2. Capitaliser sur les concepts proches

Chaque OS mobile utilise son propre langage de programmation et arbore ses propres APIs mais les concepts généraux restent standards et communs. On peut se permettre de capitaliser des concepts communs entre différentes plateformes permettant de modéliser une application de manière générique, citons par exemple :
  • Activité : correspond à une page de l’application, elle est une notion commune à tous les OS. Une application est composée d’une ou de plusieurs activités.
  • Gestion des données de l’application : en séparant le code de l’interface graphique et le code fonctionnel.
  • Vues et actions associées : une vue est un objet graphique par lequel l’utilisateur interagit avec l’application ce qui provoque une action liée à la vue. Nous retrouvons la plupart des vues sur tous les OS mobile : bouton, saisie de texte, label, barre de navigation, bouton radio, case à cocher, etc.
  • Type d’évènements : une application doit prendre en charge certains évènements susceptibles d’apparaitre durant son exécution tels que les appels téléphoniques, les SMS, etc.
  • Applications natives : les applications natives telles que le calendrier, les contacts, les alarmes, le lecteur média sont communs à tous les OS.
L’approche MDA divise la conception de l’application en deux points de vue :
  • Un point de vue "fonctionnel" indépendant des détails liés à la plateforme d’exécution. On définit ce que l’on veut générer (le quoi). Dans cette partie, on modélise des notions abstraites telles que des écrans, boutons, objets métier, DAO, mais en restant indépendant de leur implémentation technique. Modéliser le fonctionnel de l’application assure la pérennité des savoir-faire.
  • Un point de vue "technique" dans lequel sera décrit l’architecture de la plateforme d’exécution. On définit comment on veut le générer (le comment). Dans cette partie, on spécifie comment la notion fonctionnelle doit être générée : quel langage (Objective C, Java), quelle version (Android 4.1 par exemple), quelle implémentation de BDD. Modéliser l’architecture technique assure la prise en compte de la plateforme d’exécution.
L’étape qui suit la description fonctionnelle et technique d’une application est la génération du code source, c’est le rôle du générateur (ex. MIA Studio, Acceleo). Il s’appuie sur le modèle fonctionnel et technique de l’application pour générer du code source que le développeur pourra enrichir manuellement (le traitement algorithmique et les ressources qui ne peuvent pas être déduits du modèle). La modélisation nous assure une pérennisation du savoir fonctionnel. La génération de code assure un gain de temps considérable entrainant un gain de productivité.

3. Elargir l’écosystème mobile

L’écosystème - tout ce qui vit autour d’une plateforme pour en faciliter le développement - existant sous JavaEE/.NET est large, mais sur plateforme mobile, cet écosystème est encore réduit. L’utilisation de librairies tierces dans les applications mobile est limitée par les différents OS pour plusieurs raisons :
  • Une taille d’application importante : l’utilisation massive de librairies est au contraire des bonnes pratiques pour le développement mobile (problématique d’espace mémoire).
  • Corrolaire du point précédent : une taille d’application trop importante peut être un frein à son téléchargement (debit limité et frais des réseaux 3G).
  • Le manque de visibilité des développements des librairies. Alors que les librairies pour applications JEE/.Net sont portées par de grands éditeurs (JBoss, Spring, Microsoft, etc.), les librairies mobile existantes sont quasi-exclusivement développées par des développeurs tiers. Le suivi et la maintenance ne sont donc pas toujours assurés.
  • Les éditeurs Google, Apple, Microsoft gardent la main sur les évolutions des SDK et ne garantissent donc pas la compatibilité des librairies tierces avec les nouvelles versions des plateformes.
Pour assurer la pérennité du code et élargir son périmètre de compatibilité à plusieurs versions, il est donc préférable d’être indépendant au maximum des librairies tierces et d’avoir un code standard au SDK. L'approche MDA réduit le temps de développement en générant du code standard au SDK, en respectant les bonnes pratiques d’architecture et de qualité.

4. Industrialiser le développement

La mise en place d’une approche MDA, conjointement avec les différents composants d’une usine logicielle (construction, Intégration continue, analyse qualimétrique), industrialise le développement et assure une bonne qualité au code.
L’industrialisation avec le MDA nécessite plusieurs éléments clés :
  • La mise en place d’un POC par une équipe d’architectes logiciels. Ce POC servira de base de code attendu pour faciliter la réalisation du générateur.
  • Un code généré ne doit pas être source d’erreurs et doit rester compatible avec les niveaux de qualimétrie logicielle (qualité, architecture).
  • Une formation des développeurs à l’utilisation du DSL et du générateur.
  • Un support technique permettant d’accompagner les développeurs sur les outils afin d’assurer un bon démarrage du projet.
  • Une communauté autour du générateur qui remonte les bugs. L’amélioration en continue du générateur profite aux développements en cours et aux prochains projets.
  • Une capitalisation sur les bonnes pratiques de développement afin de développer des futures applications encore plus rapidement.
Sur le marché, il y a encore peu de développeurs avec des compétences “mobile”. L’industrialisation des développements mobile par l’approche MDA, a encore plus de sens dans ce contexte, car il permet d’avoir un meilleur accompagnement et un meilleur suivi.

5. Réduire le coût de possession

Avec des budgets toujours plus serrés, les entreprises veulent réduire le coût de possession de leurs applications. L’approche MDA, et plus spécifiquement le DSL et le générateur de code ont une grande valeur de capitalisation et de réutilisabilité. Elles permettent ainsi de réduire les coûts de possession, notamment sur l’investissement initial et le coût de maintenance  :
  • Une conception facilitée par un DSL adapté, cadrant les besoins spécifiques aux plateformes mobile. 
  • Un générateur de code disponible “sur étagère” et utilisable rapidement permet de booster le démarrage d’un projet
  • Réduction du support technique : le code ou les patterns complexes et qui sont enclins aux erreurs (typiquement liés à la persistance, mapping ORM) sont générés.
  • Un code de qualité suivant les bonnes pratiques assure une meilleure maîtrise et une réduction des coûts de maintenance
  • Un processus itératif : l’outillage MDA par amélioration continue va réduire les coûts des projets progressivement au fur et à mesure de son amélioration.
Un OS peut aujourd'hui être leader du marché et demain perdre certains marchés. Un exemple, avec les annonces de Samsung, premier fabricant mondial de smartphones, qui compte  sortir de nouveaux smartphones en 2013 en abandonnant Android pour Tizen. Ou encore à l’image du géant chinois Huawei qui propose son propre OS mobile ou encore plus récemment Firefox avec FirefoxOS.



En conclusion, au lieu d'investir sur la technologie qui abrite une application, mieux vaut investir dans une technique de développement qui permet de capitaliser la fonctionnalité d'une application indépendamment de sa technologie. Une méthode qui intègre l'évolutivité et la pérénité dans son processus de développement comme l'approche MDA.



dimanche 13 janvier 2013

Code trop commenté : signe de mauvaise qualité ?

Les commentaires de certains programmes m'ont toujours surpris : Soit il n'y en a pas, soit il y en a trop ... Je suis toujours surpris par la quantité de commentaire de certains programmes, surtout lorsque ceux ci n'apportent rien et qu'ils polluent la lecture du code. 

En réalité, et au risque d'en faire bondir certains, il est préférable d'avoir peu de commentaires dans du code bien écrit, plutôt que l'inverse.
D'ailleurs, une méthode trop commentée est même peut-être un signe que quelque chose est louche, comme le dit si bien Martin Fowler.
Ne vous inquiétez pas, je ne dis pas que les développeurs ne devraient pas écrire de commentaires. Dans notre analogie olfactive, les commentaires ne sentent pas mauvais ; en fait ils sentent plutôt bon. La raison pour laquelle nous mentionnons les commentaires ici est qu'ils sont souvent utilisés comme déodorant. C'est étonnant de remarquer que souvent, un code généreusement documenté est en fait vraiment mauvais.

Les commentaires nous guident vers du mauvais code qui a toutes les mauvaises odeurs dont nous avons discuté dans le reste de ce chapitre. Notre première action est de supprimer cette "mauvaise odeur" en refactorant. Et dès que nous avons fini, nous nous rendons compte que les commentaires sont superflus.

Si vous avez besoin d'un commentaire qui explique ce qu'un bloc de code fait, essayez d'extraire la méthode. Si la méthode est déjà extraite mais que vous avez toujours besoin d'un commentaire pour expliquer ce qu'elle fait, alors renommer la. Si vous avez besoin de définir quelques règles à propos de l'état du système, introduisez des assertions.

Quand vous sentez le besoin d'écrire un commentaire, essayez d'abord de refactorer le code pour que chaque commentaire devienne superflu. Un bon endroit pour utiliser un commentaire est quand vous ne savez pas quoi faire. En plus de décrire ce qu'il fait, les commentaires indiquent les points sur lesquels vous n'êtes pas sûr. Un commentaire est une bonne place pour dire pourquoi vous avez fait quelquechose. Ce type d'information aide les futurs développeurs qui reprendront votre code, et spécialement ceux qui oublient vite.
Martin Fowler

Avoir un outil de qualimétrie (type Sonar) qui oblige les développeurs de mettre des commentaires Javadoc peut donc être contraignant sur certains aspects car il peut pousser à mettre du commentaire superflu sans aucune valeur ajoutée, car cet outil ne fait qu'une analyse du code source sans intelligence, sans contexte.

Quelques contre-exemples assez problématiques (issus de vrais code source sur de vrais projets !!) sur les accesseurs :

/**
* Accesseur en écriture sur l'attribut Name
* @param newName Nouveau nom à assigner à l'attribut name **/
public String setName(String newName) {
    this.name = name;
}
/**
* Accesseur le lecture sur l'attribut Name
* @return l'attribut Name
*/
public String getName() {
    return this.name;
}

Ou dans certains cas, quand un développeur prend conscience du peu d'intérêt du commentaire mais DOIT respecter les règles imposées par l'outil de qualimétrie (Sonar en l'occurence dans l'exemple suivant) et sort l'astuce du point commenté pour le code soit sans violations !

/**
* .
**/
public int getName() {
    return this.name;
}

En réalité le code des accesseurs est beaucoup plus lisible sans aucun commentaire : 
public void setName(String name) {
    this.name = name;
}

public int getName() {
    return this.name;
} 



Ceci nous amène à plusieurs règles pour l'écriture de bons commentaires :
  1. Privilégiez le pourquoi et non pas le comment. Documentez les classes et les opérations pour décrire leurs effets et leurs objectifs sans référence aux moyens par lesquels ils le font. Le commentaire ne doit pas faire référence aux détails d'implémentation (Cette règle s'applique également en tant que règle de nommage des classes et opérations).
  2. Ne dupliquez pas les commentaires entre les interfaces et les classes d'implémentations. En cas de refactoring, il sera difficile de maintenir une documentation à jour aux différents endroits. Il est préférable de positionner le commentaire sur l'interface et de laisser la classe d'implémentation sans commentaire. 
  3. Privilégiez la concision des commentaires. N'oubliez pas qu'un commentaire est rarement lu, surtout s'il est long. Il est préférable de vérifier automatiquement la validité de paramètres dans le code avec des assertions plutôt que d'écrire dans le commentaire ce qui est attendu.
  4. Privilégiez les conventions de codage pour comprendre l'objectif d'une méthode. Par convention, on sait qu'une méthode commençant par get est un accesseur en lecture. Même chose avec les méthode set qui indique un accesseur en écriture. Il n'est pas nécessaire de ré-expliquer un comportement dont la lecture du code saute aux yeux !
  5. Privilégiez un vocabulaire commun à tous les développeurs pour que chacun puisse appréhender rapidement le sens d'une fonction juste en lisant son nom. En réalité, il est préférable de nommer correctement une méthode plutôt que d'écrire du commentaire pour expliquer ce qu'elle fait. Il peut être utile de définir une liste de mot-clés à utiliser pour que les développeurs s'appuient sur une même convention de codage.
  6. Prenez du recul sur le besoin d'un commentaire. Ne vous forcez pas à écrire un commentaire parce que l'outil de qualimétrie a remonté une violation, ou parce qu'un taux de commentaire minimal n'est pas respecté. Posez vous la question "Est ce que ce commentaire a une valeur ajoutée ?" si la réponse est non, alors supprimer le !  

L'info en plus : Personnaliser cette règle sous Sonar

  • La Javadoc n'est pas requise sur une méthode annoté @Override. Le commentaire sera automatiquement hérité. (Privilégiez cette approche à l'utilisation de inheritDoc qui nécessite un commentaire). N'hésitez donc pas à en tartiner les méthodes déjà commentées dans les interfaces et dans les classes parentes (notamment equals, hashCode, toString, etc.);
  • le paramètre allowMissingPropertyJavadoc de Sonar permet de ne pas remonter d'erreurs pour les getter et setter non commentés.

Pour aller plus loin, je vous conseille les lectures suivantes :