lundi 22 septembre 2008

NAnt

Pourquoi utiliser NAnt, MSBuild, ou make :
Je reprends cette définition
Ant est un projet open source de la fondation Apache écrit en Java qui vise le développement d'un logiciel d'automatisation des opérations répétitives tout au long du cycle de développement logiciel.

make est à Unix ce que Ant est au Java,
NAnt (au même titre que MSBuild) est au .NET ce que Ant est au Java.

J'ai utilisé NAnt, car il est très proche de Ant et donc s'adresse à un publique
plus large que MSBuild.

Voici un cas concret que NAnt nous aidera à résoudre :


  1. J'ai un web service qui doit être déployé sur IIS, qui est dépendant d'une base de donnée.

  2. J'ai un client console qui accède a ce web service.

  3. J'ai fini de développer ma solution sur mon poste,

  4. Je crée 2 installeurs, un pour le web service, un pour le client.

  5. je vais copier tous les fichiers sur mon environnement de test.

  6. je configure la base de donnée sur l'environnement de test.

  7. J'installe les msi à la main sur l'environnement de test.

  8. Je lance les tests d'intégration (ou manuel)



Et là c'est le drame ! Ca ne marche pas comme prévu (et je vous l'assure ça ne marchera jamais comme prévu),
je corrige le problème sur mon environnement de développement et recommence à l'étape 5.

Les étapes 5 6 7 8, peuvent facilement faire perdre 2 jours de travail sur 5 !
En effet, le temps de transférer les msi, installer les msi, configurer la base... ajouter à cela les erreurs d'inatention... Pour une architecture pas forcément très complexe je perd près de 5 a 10 minutes à chaque fois.
Ajouter à ça un changement de contexte important pour le développeur (on le sort du nuage sur lequel il était pendant qu'il développait, pour faire une tâche mécanique).

Je pourrais facilement ajouter d'autres étapes à faire suivant l'ampleur du projet :
par exemple nous devons refaire ces 4 étapes s'il y a plusieurs environnements de test.

Pourquoi utiliser NAnt (ou Ant) plutot que make :

make est un outils orienté shell et plutôt rudimentaire.
Ant est beaucoup plus complet, il permet en particulier d'appeler des méthodes pour l'automatisation des tâches.

En quoi il va s'intégrer avec un Serveur d'intégration comme Cruise Control ?

Non seulement Ant automatisera le déploiement sur le serveur d'intégration, mais grâce au serveur d'intégration
le développeur n'aura même pas à s'occuper de transférer les sources, et les binaires sur le serveur.
Un simple commit sur son source code control suffira à déclencher tout le processus, et avoir des rapports détaillés sur ce qu'il s'est passé (sur une interface web).
De plus, les tâches à effectuer pourront être codées dans son langage de développement adoré (code qui pourra aussi être testé),
il ne sortira ainsi pas de son environnement de développement :)
Cruise Control sera traité dans un autre post.

Voyons en pratique comment ça marche !



DLL

Comme d'habitude n'hésitez à me signaler les erreurs d'orthographes... :p

mercredi 17 septembre 2008

Introduction : Serveur d'intégration

Pourquoi un serveur d'intégration
"Ca marche sur ma machine je ne comprends pas...", oui beaucoup de développeur sont souvent pris au piège, alors que 99% du code est fini le pourcentage restant est en général le plus long.

-Sorti de l'environnement de développement le programme ne marche plus !
-Votre meilleur ami ne peut pas compiler les sources.
-Les commerciaux vous demandent de fournir la dernière version du logiciel.
-Les utilisateurs veulent à disposition la doc de la toute dernière version.
-Le manager vous demande des comptes sur les retards, et l'avancement du projet.
-La machine à café ne marche plus.

Et vous dans tout ça vous devez fermer visual studio (ou éclipse et netbean pour ne pas être raciste), et tel un poisson hors de son bocal, vous répondez aux besoins de tout ce beau monde.

Bien que le serveur d'intégration ne puisse pas réparer de machine à café,
il vous permettra de gagner énormément de temps sur les autres points.

Pourquoi j'en parle sur ce blog pourtant dédié au design logiciel ?
Tout simplement car la distribution, l'installation, la documentation, le bug tracking, le suivi d'un logiciel est une partie intégrante du logiciel, géré artisanalement ça peut devenir très vite décourageant, long et difficile.

Le serveur d'intégration est un moyen de simplifier tout ceci.

Tout ce qui peut être automatisé le sera. Que vous n'ayez à penser qu'a ajouter des nouvelles fonctionnalités à votre logiciel, plutôt qu'à zipper, copier coller des dossier, installer, faire des comptes rendus.

Je précise que pour des logiciels très très important (Windows Server par exemple) il y a des personnes qui travaillent à plein temps sur le processus de build.

Dans les posts suivant je parlerais de tout ce qui concerne l'intégration c'est à dire :

-Serveur d'intégration (Cruise control) : logiciel qui track les changement d'un gestionnaire de code source, et affiche à l'aide d'une interface graphique (web) différent rapport sur le résultat d'un build, de ses tests, de son déploiement etc...
-Nant (ou ant pour java) : utilitaire utilisé pour effectuer des taches automatiques de façon assez poussé (il va compiler,mettre en place un environnement de test, déployer, exécuter les tests, mettre à disposition la nouvelle version à tout le monde si les tests et le build passe ...)

mardi 9 septembre 2008

MVC Remanié

Présentation de MVC ?

Le pattern MVC (Modele Vue Contrôleur) est un pattern au niveau de la couche de présentation.
Son but est de souder de manière uni-directionnelle ou bi-directionnelle un objet métier à sa représentation graphique.
La "glue" de la vue et de votre objet métier s'appelle un Controleur.
Le but est de ne pas coupler votre objet métier à l'interface graphique, et vice versa.
(Ca signifie qu'une modification au niveau de votre classe métier n'impliquera pas de
modification au niveau de la vue et vice versa).

Où est le mal ?

Il n'y a aucun problème lors de "binding" unidirectionnel de la vue à votre objet métier (c'est le cas lorsque la vue est implémentée dans des technologies web telles qu'ASP.NET JSP ou PHP).
En bi-directionnel cependant c'est plus complexe.
Pour que votre objet métier puisse notifier la vue (par l'intermédiaire du controleur) d'un changement il faut implémenter le
pattern Observable sur l'objet métier.

1er souci : Le pattern plutôt orienté sur la couche présentation est en train d'imposer une implémentation à votre classe métier (classe métier n'étant peut être pas sous votre contrôle).
2eme souci : L'implémentation en question alourdit considérablement le code de votre objet métier.
La logique métier devient moins identifiable.
J'insiste sur le point qu'une couche métier en théorie ne doit contenir AUCUN couplage technique, que ce soit direct comme des références sur des objets techniques (que ça soit la persistance par exemple, une exposition par web service etc...), ou indirect (comme une imposition d'un constructeur nul, ou d'un pattern quelconque qui n'a pas d'utilité pour la clarté du domaine métier).

Le métier des autres est une chose suffisamment complexe en lui même, ne le rendons pas plus difficile qu'il ne l'est déjà.


Comment régler le problème ?

J'utiliserai le framework Spring .net pour l'exemple, la solution se base sur l'AOP
et les proxy dynamiques :

1. Créer un advice (on appelle aussi cela un interceptor, voir proxy dynamique) qui notifie les accès
aux setter d'un objet (mettre le pattern observable sur l'advice).
2. Encapsuler la création de l'objet métier dans une factory (la factory fera un proxy dynamique sur votre objet métier)
3. Créer votre controleur en utilisant les techniques traditionnelles pour binder la vue vers votre objet métier.
4. Le controleur crée l'advice de l'étape 1, s'abonne à l'événement de changement de setter.
5. Le controleur incorpore l'advice au proxy.

Résultat :
-Un objet métier et une vue soudés en bi-directionnelle,
-Aucun code de gestion d'événement au niveau de notre objet métier.

Assez de blabla, voyons ça en pratique avec mon podcast et gloire au framework Spring ! ;)
Il y a 2 parties : Un rappel sur le pattern MVC classique, et ma proposition d'implémentation aidée par l'AOP.
Je tiens à souligner que comme tout les patterns, cette implémentation en est une parmis d'autres, j'ai essayé de communiquer mon idée le plus simplement possible.


DLL

Mon pattern MVC est un peu différent de ce que vous voyez dans la littérature, car c'est mon controleur qui reçoit les modifications du model et non directement la vue.
Ma raison est, comme je l'ai dit dans le podcast, de garder la vue et le model indépendant (étant donné que j'ai réutilisé un contrôle Winform sorti de la boite :)).Ainsi lors d'un changement de code au niveau du model les modifications sont localisées seulement au niveau du controleur.

ps: n'hésitez pas à me signaler les fautes d'orthographes, de grammaire et de français (ce blog me permet aussi d'apprendre à écrire ! :)... c'est pas gagné ! ).

mercredi 3 septembre 2008

Programmation par contrat par les tests unitaires

Programmation par contrat, c'est quoi ?

Puisque la programmation par contrat est complémentaire de l'orienté objet, mais peut aussi s'étendre a
du procédurale, je parlerais ici "d'operation".
Ce terme regroupera les "fonctions" et les "méthodes".

Le fondateur de ce concept est Bertrand Meyer dans son livre Conception et programmation orientées objet et son language Eiffel.
Le concept est très simple : toute opération (méthode en poo, sinon une fonction)
vérifie ses parametres a l'aide de pre-condition (on ne peux pas inséré un objet null dans un tableau), si elles sont respecté
ll'opération s'engage à respecter les post-conditions (après insertion d'un élément dans le tableau, sa longueur a été incrémenté de 1).
On peut ajouté a nos classes des invariants, ce sont des règle sur l'état
de notre objet qui sont immuables (un tableau possède une taille supérieur ou
égale a 0).

Les post conditions, pre conditions et invariant font partie de la signature de la méthode et de la définition de la classe.
C'est bien ici la différence avec la programmation défensive : le corps de notre méthode reste clair (pas de gestion d'exception abusive, qui cache le comportement de notre méthode), et ne nécessite pas de documentation externe.

L'énorme intéret de ce paradigme est que 90% des erreurs de programmation (les fameuses erreurs "impossibles") sont détéctés par le compilateur.
Ainsi si une opération s'est déroulé sans exception les post conditions sont respéctées.

Ainsi le compilateur vous averti a tout moment lors de l'appel d'une opération si les paramètres risque de ne pas respécter les pré-conditions (en se basant sur les contrats que que l'on a certifié sur un certains objets en paramètres).

Avec ce paradigme nous pouvons presque prouver qu'un programme est correct, qu'il n'aura pas de comportement imprévu.

En .NET il existe le Spec# qui est une extension du C# qui prend en compte ce paradigme, j'ai eu l'occasion de le tester et je ne suis pas convaincu.
En effet seul les préconditions de paramètres différents de null sont pris en compte au moment de la compilation. Le reste est effectué au runtime.
J'attends avec impatience le Sing#, évolution du Spec# et language officiel du nouveau noyau de windows en développement : Singularity.

C'est super, mais les tests unitaires dans tout ca ?

Redescendons sur terre, les seuls languages assez productifs en entreprise connu sont simplement orientés objet (java, c# pour n'en citer que 2).
Maintenant vous voulez pouvoir définir les méthodes de vos classes ou interfaces de manière plus detaillé ?
C'est à dire mettre des invariants, spécifier des exceptions a lancer en cas de mauvaise pré conditions, et spécifier des post conditions ?

La mauvaise nouvelle c'est qu'actuellement vous ne pouvez rien faire pour que le compilateur s'occupe de ces problèmes pour vous.
La bonne nouvelle c'est que les tests unitaires peuvent vous faire tendre vers ce modèle.

Ce podcast vous montrera plusieurs best practices de test unitaire :
-Comment réutiliser des tests déjà existant, (écrivez moins pour tester plus...)
-Comment écrire des tests avant toute implémentation,
-Nom révelateur de test.
-Bien utiliser l'Héritage de fixture.
-Les tests en tant que documentation. (nous on développe, on sait lire et écrire .c,.h,.cpp,.java,.cs mais pas du .doc)

Ce podcast est réalisé en C# sous visual studio, mais n'est pas borné à être appliquer dans le monde du .net.
Vous faites du java, du python, du C/C++ ... et vous voulez vous aussi faire des tests unitaires ?
Une seule adresse (qui en contient plusieurs) c'est ici.

Je réflechirais sur une façon d'effectuer des vérifications au runtime sur les paramètres de méthode et des invariants,
sans avoir a mettre le moindre code défensif dans le corps de la méthode à l'aide de proxy dynamique.


DDL

Je n'ai pas détaillé ma classe de base, BaseContract car c'est un choix d'implémentation personnel et il peut y avoir d'autre choix.
Si ca interesse je pourrais mettre le code source de l'exemple à disposition.