RSS Feed

Archives de la catégorie ‘Conception’

SOA – Introduction à l’architecture orientée services

7 July 2008 par SeB 4 commentaires »

L’architecture orientée services est plus communément connue sous le sigle SOA pour Services Oriented Architecture. Cette notion est de plus en plus en vogue. Et tout laisse à penser que ce n’est pas prêt de s’arrêter.

Mais qu’est-ce que la SOA ?

Lorsque l’on pose cette question, la réponse la plus courante est : “les services web”. Or, je trouve que cette réponse est très réductrice. C’est comme si l’on définissait une architecture client/serveur par le TCP/IP. En effet, les services web ne sont qu’un moyen de mettre en place une architecture orientée services et d’atteindre ses objectifs. Mais la SOA ne se limite pas qu’à une simple technologie.

Il est très difficile de définir la SOA en quelques mots. Ce qu’on ne peut retenir, c’est que la SOA permet de répondre au problème du fonctionnement en silo d’une entreprise (suite aux multiples fusions, rachats, sites différents, évolutions technologique, etc…) qui empêche de gérer le SI d’une société dans sa globalité.

La SOA est une autre façon d’intégrer les briques ou composants logiciels au sein du SI de l’entreprise. Cette méthode s’attache à décomposer chaque composant en un ensemble de fonctions basiques appelées services. L’objectif étant de pouvoir réutiliser simplement ses services. Les utilisateurs de ceux-ci peuvent être d’autres services, des logiciels de l’entreprise, des applications externes, etc…

Comment mettre en place une SOA ?

On ne peut pas encore dire qu’il existe une méthodologie pour mettre en place une telle architecture. On peut seulement souligner une initiative française : Praxeme. Cette association tente de définir une méthodologie (libre de droit) pour mettre en place une SOA.

Les principes généraux de la SOA

Une architecture orientée services repose sur quelques principes forts :

  • Les services exposent des fonctions qui nécessitent des paramètres d’entrée et retourne une réponse dont les interfaces sont publiées.
  • La description du service : nom, paramètre, contrat de service, etc…
  • Les services sont sans état et ne gèrent aucun contexte.
  • La localisation des services via un annuaire.
  • Des couplages externes lâches pour faciliter la réutilisation des services.
  • Les services peuvent être synchrones ou asynchrones.

Tous ces principes sont respectés par les plateformes de services web. C’est pourquoi la notion de SOA est étroitement liée aux services web.

La SOA doit également son récent succès à une vision stratégique à long terme qui repose sur l’urbanisation du SI.

Les adeptes de la SOA vous parlerons également de l’agilité (à ne pas confondre avec les méthodes agiles !). En effet, lorsque l’urbanisation du SI est réalisée correctement, le couplage faible des services permet de redéfinir les processus de l’entreprise très rapidement; d’où l’agilité.

Comme vous pouvez le constater, je n’ai fait que survoler le sujet. Et il me reste encore beaucoup de chose à dire. Si le sujet vous intéresse, je tacherai d’écrire un peu plus articles sur le sujet. Et pourquoi pas, ouvrir une nouvelle section SOA. :-)

 

Appliquer le modèle MVC en Ajax

22 September 2006 par SeB 2 commentaires »

Je vous ai souvent parlé du modèle de conception MVC et de ses avantages.

Ajaxian vient de relater un article de PHPied sur la mise en application du modèle MVC avec Ajax.

Selon l’auteur, avec Ajax, la vue contient des pages HTML, des feuilles de style CSS et des scripts Javascript pour la mise à jour du HTML. Le contrôleur contient des scripts Javascripts pour les comportements et du code PHP pour aiguiller les requêtes. Et pour finir, le modèle contient la logique métier en PHP.

A partir de ce modèle, l’auteur a écrit une petite démonstration dont le code source est accessible. Il propose même un squelette de projet pour les nouveaux projets. La couche Ajax est implémentée avec YUI.

L’approche, même si elle reste simpliste, est réellement intéressante. Elle permet de se poser des questions sur l’organisation du code dans les applications qui utilisent Ajax.

 

Répartition du développement verticale ou horizontale ?

1 July 2006 par SeB 4 commentaires »

Lorsqu’un projet a une taille conséquente, il est nécessaire de répartir les tâches de développement entre les développeurs. Avec le développement multi-couche, cette répartition peut se faire de deux façon différentes :

  • L’approche horizontale
  • L’approche verticale

Selon Mastering EJB 3rd Edition[1], l’approche horizontale permet d’avoir des personnes ultra-spécialisées dans un domaine technologique correspondant à la couche sur laquelle ils ont l’habitude de travailler. Alors que l’approche verticale permet aux personnes d’obtenir une excellente maîtrise du fonctionnel lié au métier.

La première approche donne naissance à des experts dans des domaines spécifiques. Et avec le second point de vue les intervenants sont des généralistes et progressent dans tous les domaines technologiques.

Par expérience :

  • L’approche horizontale :
    • rallonge les temps de développements (à cause des problèmes d’intégrations)[2]
    • réduit les retours lors de la recette (grâce aux contrôles des n développeurs travaillant sur le même use case et qui confrontent leur avis)
    • le planning est plus difficile à organiser et maintenir à cause des dépendances (avec la pyramide des composants, il faut être capable d’ordonnancer correctement les développements) à moins de faire de l’IoC (par exemple avec Spring)
    • risque d’ennui des développeurs s’ils sont toujours sur la même couche logicielle
  • L’approche verticale :
    • optimise les temps de développements
    • les développeurs ont une vue d’ensemble du service
    • la planification est beaucoup plus simple (grâce au découpage par use case)
    • les développeurs progressent dans plusieurs domaines technologiques simultanément[3]

Aucune des deux approches ne semble surpasser l’autre. Personnellement[4], je préfère la répartition horizontale car elle permet d’obtenir une meilleure qualité des développements (d’un point de vue fonctionnel).

Et vous, comment faites-vous ? Quelle approche préférez-vous ?

Notes

[1] Voir le chapitre 20 page 603.

[2] Si les développeurs travaillent toujours sur la même couche, la tendance peut s’inverser (au détriment d’une certain monotonie).

[3] C’est un facteur de motivation non négligeable qui joue également sur la qualité des développements.

[4] Pour avoir expérimenté les deux méthodes.

 

La revue de code pour améliorer la qualité des développements

28 June 2006 par SeB 1 commentaire »

Pour fournir un logiciel de qualité, il est nécessaire de produire un code source de qualité. Je vous ai déjà présenté des outils pour mesurer des indicateurs de qualité du code source et pour vérifier le respect des conventions de codage. Cependant, ces outils ont leurs limites. Ils tendent à améliorer le code source en contrôlant le respect des normes de codage ou en identifiant les défauts de conception. Par contre, ils ne permettent pas d’identifier les anomalies fonctionnelles.

Cédric Beust présente son point de vue sur l’intérêt de la revue de code. La revue de code permet d’identifier des bugs avant de les rencontrer au moyen d’une relecture du code source par un développeur expérimenté.

La mise en place d’une revue de code systématique pendant la phase de développement et de correction, les développeurs se responsabilisent encore plus[1]. Car ils savent que leur travail sera automatiquement évalué[2]. Ce système permet d’améliorer la qualité du code source écrit. De plus, le relecteur pourra identifier des bugs ou des axes d’amélioration[3].

Trois processus de revue de code existent :

  • Revue de code bloquante : tout développement doit être relu avant d’être commité dans le référentiel du code source. Ce mode est un frein au développement car certains développement peuvent se retrouver en attente d’une relecture de développement dont ils dépendent.
  • Revue de code non-bloquante : tout code source commité dans le référentiel du source source doit être relu. Cette méthode permet au développeur de continuer son travail sans attendre la relecture. De même, le relecteur n’est pas obligé de se précipiter pour relire le code.
  • Revue de code avec le développement par binôme : c’est une conséquence de l’extrême programming. Cependant le travail en binôme influence le jugement du relecteur direct.

La revue de code non-bloquante semble être la meilleure solution. Des produits permettent de mettre en place ce système. Certains sont même disponibles sous la forme de plugins pour les IDEs tel que Jupiter pour Eclipse.

La revue de code augmente les charges de développement d’un projet. En revanche, cette première passe permet d’éviter de nombreux retours lors de la phase de recette. La charge de recette et de correction sont alors réduites. Le produit livré sera mieux perçu par les premiers utilisateurs.

A vos relectures ! ;-)

Notes

[1] Plus attentif aux potentielles erreurs, documentation du code, …

[2] Attention, l’évaluation doit être respectueuse du travail initial fourni.

[3] Optimisation du code source, documentation, …

 

Une participation insignifiante parmi les couches applicatives

12 June 2006 par SeB 4 commentaires »

La réutilisation de couche logicielle existante ne date pas d’aujourd’hui. Mais ce modèle de conception est encore plus d’actualité avec l’essor des applications web.

En effet, pour réaliser une application web, nous allons choisir un serveur d’application, un framework MVC, une couche de persistance, un accès JDBC, … Ajoutez à tout cela, d’autres couches applicatives pour le cache, la répartition de charge, le workflow et vous vous retrouvez avec une pléthore de composants !

Christophe J. présente un article de Peter Thomas illustrant très bien ce fait. Dans son article, il se demande quelle proportion son travail occupe-t-il entre une requête HTTP et l’accès à la base de données en JDBC ? Pour cela, il a utilisé un profiler pour afficher la pile d’appels[1].

C’est assez terrifiant, mais extrêmement réaliste. Le code spécifique à l’application occupe une part très limitée de la pile d’appels. Votre participation dans l’application est-elle insignifiante ? Oui et non[2]. Certe, votre code ne représente pas grand-chose dans l’ensemble de l’application. Mais c’est la valeur ajoutée qui fait la différence. De plus, il ne faut pas oublier tous les fichiers de configurations[3]. Ceux-ci ne sont pas visibles dans la pile d’appels. Pourtant, ils représentent une part significative dans la logique de l’application.

Donc, même si votre participation dans l’écriture du code d’une application diminue progressivement, vous apportez une valeur ajoutée non négligeable et essentielle. Aujourd’hui, le travail des développeurs s’apparente à de la plomberie. Et ceci est en partie rassurant. En effet, vous ne perdez plus votre temps à réécrire ce qui existe déjà, et vous vous concentrez le cœur du métier.

Notes

[1] La taille du code compilé peut être un indicateur également. Mais pas réaliste puisque pour une API, toutes les fonctionnalités ne sont pas forcement utilisées.

[2] Doit-on répondre en bon normand. ;-)

[3] Paramétrage du mapping, du modèle MVC, ordonnancement des flux applicatifs, etc…

 

Concevoir une application multilingue

8 June 2006 par SeB Pas de commentaire »

Comment concevoir une application multilingue ? Quelle architecture mettre en place pour internationaliser une application ?

Le contexte applicatif

Avant d’aller plus, loin il est nécessaire de définir les différents contextes applicatifs qui peuvent conditionner le choix d’une solution multilingue.

Les données

Les données à traduire peuvent être séparées en deux groupes :

  • les données statiques : qui correspondent aux messages de l’application[1].
  • les données dynamiques[2] : ce sont des informations, généralement stockées en base de données, qui sont saisies par les utilisateurs.

Les utilisateurs

Une application peut être mono-utilisateur ou multi-utilisateur. Pour une application mono-utilisateur, seules les données statiques ont besoins d’être multilingues. En revanche, dans une application multi-utilisateurs, deux cas sont possibles :

  • les données applicatives sont exclusivement réservées à chaque utilisateur
  • les données applicatives sont partagées entre les utilisateurs

Dans le premier cas, l’internationalisation des données applicatives n’est pas nécessaire. Car chaque utilisateur produit ses propres informations dans sa langue. Par contre, le second cas mérite plus d’attention. Surtout si les utilisateurs n’ont pas tous la même langue.

Internationalisation

Les données statiques

Pour les données statiques, il suffit seulement d’externaliser tous les messages dans des fichiers de ressources[3]. Ensuite, il suffit d’écrire autant de fichier de ressources que de langues supportées par l’application. Ainsi, lorsque l’utilisateur accède à l’application, les messages sont récupérés à partir du fichier correspondant à sa langue.[4].

Les données dynamiques

Les données utilisateurs qui doivent être traduites doivent être stockées en base de données. Et c’est la base de données qui gère les traductions. Pour cela, il faut définir une table listant les langues. Puis pour chaque entité qui peut être traduite, il faut utiliser deux tables :

  • la première contient les champs qui ne sont pas traduits
  • la seconde contient les champs qui peuvent être traduits et est liée à un enregistrement de la première table et une langue

La seconde table contient autant d’enregistrement qu’il y a de langue pour un enregistrement de la première table. De cette façon, les données à retourner par la base de données dépendront de la langue de l’utilisateur.

Les limitations

Gérer des données dynamiques dans plusieurs langues oblige à saisir ces informations dans toutes les langues. De plus, cette étude ne prend pas en compte les contextes collaboratifs multilingues.

Aller plus loin

Les devises, le format des dates et les nombres ne sont pas abordés ici. Cependant, il ne faut pas oublier de les gérer. Une piste intéressante serait de stocker en base de données ces informations dans le format d’une locale par défaut[5]. Ensuite pour chaque utilisateur, il serait nécessaire de reformatter les données que ce soit à la saisie ou à l’affichage.

L’encodage des données n’est pas évoqué non plus. Mais il faut penser à encoder correctement des données dès le départ ! Car la conversion d’un encodage vers un autre est une expérience très chaotique. ;-)

De plus, cet article traite seulement des éléments textuels. Or, l’internationalisation ne dépend pas seulement du texte. D’autres éléments peuvent être pris en considération lors de l’internationalisation, comme par exemple les images, les couleurs, la mise en page[6], …

La solution proposée est une bonne base pour rendre vos applications multilingues. Cette étude ne prétend pas résoudre tous les problèmes d’internationalisation. Néanmoins, elle couvre une grande partie des cas rencontrés généralement. Le dernier travail reste de trouver des traducteurs. ;-)

Notes

[1] Les libellés de l’interface, les messages d’erreur, mais aussi les libellés des états et autres status figés du modèle de données.

[2] Elles sont appelées également données applicatives dans le texte.

[3] Des fichiers .po pour le C ou le PHP, .properties pour le Java, …

[4] Définie par le navigateur, la locale du compte utilisateur, …

[5] Par exemple en anglais si l’application est codée dans cette langue.

[6] Sans parler non plus du sens de lecture !

 

Modèle d’anti-conception pour la gestion des exceptions

24 April 2006 par SeB Pas de commentaire »

Les exceptions sont très utilisées. Pourtant, il n’est pas toujours évident de savoir comment les gérer correctement.

Tim McCune a écrit un article intitulé Exception-Handling Antipatterns où il présente les modèles d’anti-conception sur le traitement des exceptions.

Cet article donne les réponses aux questions :

  • Faut-il créer ses propres exceptions ?
  • Quand faut-il lever une exception ?
  • Quand capturer une exception ?

De son étude, on peut retenir qu’il existe deux types d’exception à créer soi-même :

  • Quand un problème survient : elle est propre à la couche applicative.
  • Pour encapsuler et lever une exception rencontrée : elle est utilisé pour masquer l’implémentation sous-jacente.

Quelques cas d’anti-conception

De plus, il nous conseille de ne pas tracer puis lever une exception. En effet lors de la capture d’une exception, il faut soit la tracer soit la lever. Mais il ne faut pas faire ces deux actions en même temps, sous peine de rencontrer les piles d’exception en double (voir plus) dans les traces.

Il est très dangereux de capturer directement l’exception générique : Exception. En effet, si le code appelé est modifié et peut lever de nouvelles exceptions, il est possible de passer à côté de nouveaux cas d’erreur non gérés.

Il faut faire attention à l’utilisation de l’encapsulation d’exception pour ne pas perdre les informations transmises par l’exception source.

De même, il n’est pas conseillé de retourner null lors qu’une exception est rencontrée. Comme son nom l’indique, une exception est un cas exceptionnel. Il faut réserver l’utilisation de la valeur null pour les cas fonctionnels.

Le traitement d’une exception peut passer par l’exécution de code de finalisation. Ce code ne doit en aucun cas pouvoir lever une exception sous peine de perdre la cause réelle la première exception.

Parfois l’implémentation de certaines méthodes ne sont pas toujours disponible. Cela se traduit souvent par l’écriture d’une méthode qui retourne la valeur null. Il est préférable de retourner une exception expliquant que la méthode n’est pas implémentée.

La gestion des exceptions, par le traitement de la cause de l’exception, fragilise le code. En effet, lorsque l’on est pas maitre du code levant l’exception, la cause de l’exception peut changer si l’implémentation change. Le code appelant compilera toujours, pourtant le résultat à l’exécution n’est pas garanti !

Quelques conseils supplémentaires

Sur le même thème, Gunjan Doshi et Jim Cushing ont écrit respectivement les meilleures utilisations de la gestion des exceptions et trois règles pour la gestion des exceptions. Les auteurs insistent sur la différence entre les classes Throwable, Error, Exception et RuntimeException en Java.

J. Cushing explique également qu’il faut lever le plus tôt possible une exception. Et de la même manière, il faut capturer le plus tard possible une exception levée. Le fait de lever le plus tôt possible une exception la rend plus spécifique et donc plus explicite. Et en capturant le plus tard possible une exception, cela permet de bénéficier d’une pile d’exception plus complète et donc plus facile à analyser.

Conclusion

La prochaine fois que vous vous posez des questions sur la façon dont il faut concevoir la gestion des exceptions dans votre application, repensez à ces modèles d’anti-conception. Celà vous permettra d’éviter quelques pièges.

 

JUnit – modèle d’anti-conception

15 March 2006 par SeB Pas de commentaire »

De plus en plus présent. Mais cet outil est-il utilisé correctement ?

JUnit est un framework de tests unitaires. Son utilité n’est plus à prouver. Beaucoup de personnes l’utilisent, mais pas toujours de la bonne façon.

Ady nous fait découvrir deux articles sur les exemples à ne pas suivre lors de l’implémentation de tests unitaires. L’article de Joe Schmetzer intitulé JUnit Anti-pattern est très bien écrit et met en évidence les pièges à éviter. Selon l’auteur, il faut éviter d’écrire des tests :

  • sans assertions
  • avec plusieurs assertions
  • avec des assertions superflues
  • avec des assertions non-adaptées
  • avec des try/catch

Dans ces exemples, ce que l’on peut souvent rencontrer ce sont les try/catch. Beaucoup de développeurs ont pris l’habitude de gérer les exceptions dès qu’il est possible d’en rencontrer une[1]. Cependant lors de l’écriture de test unitaire, il est rarement nécessaire de gérer les l’exceptions[2]. Laissez l’exception remonter jusqu’au framework JUnit !

En revanche, J. Schmetzer explique qu’il ne faut pas mettre plusieurs assertions dans un même test. Il n’a pas tord puisque la première assertion en échec masque les suivantes. Pourtant dans la réalité, l’application de cette bonne pratique peut vite devenir un vrai calvaire. En effet, un simple test avec cinq ou six assertions doit être remplacé par cinq ou six fois le même test avec pour chaque test une assertion différente. Le nombre de tests à écrit est alors considérable.

Il ne faut pas négliger la qualité de l’écriture des tests unitaire. Gardez les précédentes recommandations en mémoire.

Notes

[1] C’est une bonne habitude dont il ne faut pas trop abuser.

[2] Sauf si justement le test doit vérifier qu’une exception est bien levée.

 

L’architecture et les technologies

2 March 2006 par SeB Pas de commentaire »

Meilleurs amis ou meilleurs ennemis ?

Beaucoup de personnes disent faire de l’architecture. Or elles pensent trop en termes de technologie. La technologie c’est très bien. Cela permet de découvrir de nouveaux domaines, de faire de la gymnastique intellectuelle et de renouveller son propre intérêt. Mais la technologie est un domaine où l’on peut se perdre. Et surtout la technologie ce n’est pas l’architecture !

Les technologies passent, mais l’architecture reste. Comme le dit très bien Aurélien Pelletier dans son billet intitulé Architecture et technologies l’architecture passe avant la technologie. Mais il est nécessaire d’étudier les technologies pour en extraire l’architecture. De cette manière, l’architecte sera à même de pouvoir considérer si une nouvelle technologie est une avancé en soi. Ou il sera capable de comparer deux technologies.

Pour finir, tout comme il avait été dit précédemment qu’il ne faut pas sacrifier l’architecture pour l’optimisation; il ne faut pas sacrifier l’architecture pour la technologie.

 

MVC & MVC2 – Modèle Vue Contrôleur (Model View Controller)

9 December 2004 par SeB 22 commentaires »

Le Model-View-Controller (MVC) est un modèle de conception logicielle très répandu et fort utile. Créé dans les années 80 par Xerox PARC pour Smalltalk-80, il est aujourd’hui fortement recommandé dans l’univers J2EE. Néanmoins il faut retenir que c’est un modèle de conception, et il est donc indépendant du langage de programmation.

lire la suite…