Approcher SOA en douceur (ou le pragmatisme de rigueur)
par Fabrice Marguerie
SOA, ce terme est partout. La prochaine révolution est en marche. Mais comment l'aborder ? Devons-nous encore apprendre une nouvelle technologie et oublier la majeure partie de ce que nous connaissons aujourd'hui ? D'ailleurs, est-ce si révolutionnaire ?

aire de la SOA, voilà bien la tendance du moment ! C'est en tout cas un terme à connaître pour ne pas paraître ridicule en société. Pourtant, ce n'est pas ici que vous trouverez une définition de SOA. Je me contenterai d'introduire quelques règles et nous essayerons de déterminer ce qui change par rapport à votre existant et vos habitudes, dans le but de vous aider à préparer vos applications aux besoins de demain. Rassurez-vous, j'espère aussi vous montrer que la SOA peut vous concerner aujourd'hui et que ce ne sont pas que de belles promesses...

Je ne souhaite pas aborder les grandes théories, telles que mises en avant par Microsoft avec Indigo (intégré à Windows Longhorn) et que vous commencerez peut-être à déployer vers 2008... (et il va certainement couler de l'eau sous les ponts d'ici là...).
Il n'y a de toute façon pas de définition complète, ni de règles absolues. La SOA est encore en maturation. Je m'attacherai donc ici moins à la théorie qu'à la pratique. Je ne prendrai pas en considération l'approche SOA dans sa totalité, mais tâcherai plutôt d'en donner une interprétation personnelle.

Je veux croire que la SOA puisse être une source de bénéfices avant d'être une trop grande contrainte. Je m'attache donc à une approche pragmatique qui vous permettra d'orienter vos développements vers la SOA et concevoir aujourd'hui vos applications de manière à ce qu'elles soient prêtes pour les évolutions de demain.

Je commencerai par une rapide introduction à la SOA. Nous tâcherons de déterminer s'il s'agit d'une simple évolution ou d'une nouvelle façon révolutionnaire de concevoir les applications. Nous chercherons à comprendre s'il y a une opposition entre la SOA et la POO, puis passerons en revue quelques règles.

Nota Bene : vous ne trouverez pas uniquement dans cette article des considérations sur la SOA, mais également sur les architectures n-tiers et quelques bonnes pratiques.

Vous avez dit SOA ?

SOA, SOA... encore un nouvel acronyme à la mode pour une technologie quelconque que Microsoft et consorts cherchent à nous imposer pour leur propre intérêt...
Eh bien non, pas tout à fait. Il s'agit ici plus d'une philosophie plus que d'une technologie. Et cette philosophie, peut-être l'appliquez vous déjà sans le savoir, comme monsieur Jourdain faisait de la prose. Vous pourrez en juger par vous-même à l'issu de la lecture de cet article je l'espère.

SOA signifie "Service-Oriented Architecture", autrement dit "Architecture Orientée Services". Dans cet article j'utiliserai le terme SOA. Pourquoi ne pas utiliser un acronyme français comme AOS au même titre que POO pour "Programmation Orientée Objets" ? Simplement parce que le terme SOA est déjà très largement répandu et reconnu de tous.

Qu'est-ce que la SOA selon DotNetGuru :

"Une vision d'un système destinée à traiter toute application comme un fournisseur de services", Symposium DNG 2003

En fait, HP et IBM nous parlent de SOA depuis longtemps mais avec un sens différent. Microsoft nous promet que Longhorn sera la plate-forme idéale pour la SOA, selon sa propre définition.

La SOA est un état d'esprit, elle permet une conception axée sur l'interopérabilité et la réutilisation. La SOA peut être mise en oeuvre dès maintenant dans vos applications centralisées. C'est aussi le message que je souhaite faire passer ici.

Quelques objectifs

Les applications d’aujourd’hui ne sont plus monolithiques et doivent s’intégrer harmonieusement dans le système d’information de l’entreprise. Cela implique l’interaction avec l’existant (systèmes, plates-formes et applications), et une ouverture vers une réutilisation future des nouveaux modules fonctionnels ou techniques.

Les axes majeurs de la SOA sont :

  • La réutilisation et la composition, permettant le partage de modules entre applications et les échanges inter-applicatifs ;
  • La pérennité, qui implique notamment le support des technologies existantes et à venir ;
  • L'évolutivité, car toute application est vivante, a une certaine durée de vie, peut se voit greffer de nouveaux modules et doit pouvoir répondre aux nouveaux besoins fonctionnels ;
  • L'ouverture et l'interopérabilité, pour partager des modules applicatifs entre plates-formes et environnements ;
  • La distribution, pour pouvoir utiliser ces modules à distance et les centraliser au sein de l'entreprise par exemple ;
  • La performance, avec en priorité l'accent mis sur la montée en charge.

Ce document s’attache à définir des critères importants qui faciliteront plus tard une ouverture des applications sur ces axes.

Bien sûr, vous n'êtes pas forcément concernés par l'ensemble de ces objectifs. Encore une fois, il faut plier les règles théoriques à vos besoins, en en sacrifiant quelques unes si elle n'apportent pas de valeur dans votre cas. Par exemple, on pourra parfois optimiser ses applications pour la plate-forme de son choix (.NET, J2EE, ... ne soyons pas partisans) en sacrifiant l'indépendance vis à vis de cette plate-forme mais en gagnant en performance.

Architecture multi-couches

Les architectures multi-couches sont maintenant bien acceptées et mise en œuvre dans les applications. Une des premières questions qui se posent lorsque l'on commence à parler de SOA et l'impact sur les couches logiques ou physiques des applications.
Notre premier schéma permettra un rapide rappel sur une architecture classique à trois tiers :


Interactions entre les couches d'une application à trois tiers

De manière à tirer le maximum de bénéfices d’une architecture de ce type, un ensemble de points sont à respecter. Ces points concernent d’un côté les interactions entre les couches, et de l’autre chacune des couches elles-mêmes.

Découplage entre les couches et optimisation des échanges

Afin d’assurer de plus grandes facilités d’évolutivité et de réutilisation, il convient de découpler les couches les unes des autres.

La communication entre les couches dépendra de l’architecture physique de l’application. Lorsque les couches se trouvent sur des machines physiquement distinctes, des mécanismes tels que le remoting ou les services web pourront être mis en œuvre. Lorsque les couches d’une application se trouvent toutes sur la même machine, il convient d’optimiser la performance en privilégiant des appels directs entre les couches.

En tout état de cause, les différentes couches devront échanger des données et non des références sur des objets, de manière à grouper les données et réduire les allers-retours entre les couches.

Deux règles s’appliquent alors :

  • Les objets de données doivent être sérialisables sous la forme de flux texte ou binaires ;

  • Les objets de données doivent être découplés de leur source de données. Un objet de données peut être stocké sous différents formats et dans différents conteneurs, il convient par conséquent de ne pas inclure directement dans les objets de données le code qui assure leur persistance dans ces formats et ces conteneurs.

Nous reviendrons sur ces objets de données plus tard.

Découplage du format de stockage

Une couche d’accès aux données est chargée de dialoguer avec les bases de données, en exécutant sur celles-ci des requêtes de consultation ou de modification.

Le code contenu dans une couche d’accès aux données est intrinsèquement lié à la base de données particulière pour laquelle elle a été prévue. Par exemple, une couche d’accès aux données prévue pour Oracle ne sera pas compatible avec SQL Server ; de la même manière, une couche d’accès aux données prévue pour stocker des données au format XML ne pourra être utilisée telle quelle pour stocker des données dans un annuaire LDAP.

Dans le schéma ci-dessous, la couche BLL peut utiliser une des trois couches DAL spécifiques chacune à une base de données :

Afin de garantir l’indépendance de la couche BLL vis-à-vis d’une implémentation DAL spécifique, il convient de mettre en œuvre un mécanisme d’abstraction. Le mécanisme adéquat est décrit par le modèle dit de la Fabrication.

Le design pattern Fabrication fournit une interface pour créer des instances d’objets similaires sans spécifier les classes de leur implémentation concrète.

Ce modèle permet par exemple à la couche BLL qui a besoin de manipuler des objets Facture d’interagir avec la couche DAL associée, sans que la couche BLL ne soit conçue spécifiquement pour une implémentation particulière. Voici comment serait modélisée la DAL Facture :


Diagramme de classes de la DAL Facture

La couche BLL aurait alors à utiliser la classe DalFactory pour obtenir une DAL spécifique, pour ensuite manipuler cette DAL à travers l’interface IDalFacture.

SOA, évolution ou révolution

POO contre SOA

Il y a deux écoles: une orientée objets et l'autre orientée services. Peut-être appartenez vous déjà à la seconde. Peut-être êtes-vous un jusqu'au-boutiste de l'objet.
Il va de soit que c'est l'approche orientée services qui nous intéresse ici, mais il est bon de où se situent les différences. C'est une question récurrente. Voyons donc brièvement ces deux approches, afin que vous retrouviez celle que vous mettez en oeuvre.

Modèle orienté objets (POO)

Voici une architecture à trois couches classique avec un modèle objet :

On remarque tout de suite le nombre de liens entre la couche Présentation et les objets métiers.
Le code client doit jongler directement avec le modèle objet de la couche métier, ce qui a pour conséquence de lier celle-ci très fortement à un modèle spécifique et requiert un nombre d'appels important entre les deux couches. Vous comprendrez facilement que la multiplication des appels entre couches pose problème lors de la mise à disposition à distance des objets métiers, et que le nombre d'objets à manipuler réduit l'indépendance entre couches à néant et complexifie la prise en main de la couche métier.

Exemple de code :

Customers customers = Customer.List();
Orders orders = customers[0].Orders;
Order order = orders.Add("ORDER001", customerData.Customers[0]);
order.Lines.Add(new Product("53XYPR0D8"), 2);
orders.Save(); // Si la mise à jour n'a pas été faite en direct

Les objets métiers manipulés sont Customer, Order et Product. On demande ici directement à l'objet métier Order de prendre en compte les modifications. Dans certains modèles, les mises à jours sont faites en direct à chaque appel à un objet métier. Les appels au serveur sont symbolisés en gras.

Modèle orienté services (SOA)

Voici une architecture orientée services qui reposerait sur les mêmes objets métiers :

Vous remarquez que l'on a introduit un niveau d'indirection supplémentaire sous la forme de services. La couche Présentation ne manipule plus directement les objets métiers, mais passe par des services. Les objets métiers se trouvent dans des bibliothèques de classes directement chargées dans le même processus que les services, le coût des appels aux objets métiers est alors très faible.
Les services agissent comme des boites noires faisant abstraction de la complexité du modèle objet, présentant un ensemble de fonctionnalités restreints et permettant de réduire les échanges entre les couches.

Exemple de code :

CustomerData customerData = CustomerService.ListCustomers();
OrderData orderData = new OrderData();
OrderEntity order = orderData.Orders.Add("ORDER001", customerData.Customers[0].CustomerID));
order.Lines.Add("53XYPR0D8", 2)
CustomerService.AddOrders(orderData);

Le service CustomerService travaille avec les objets de données CustomerData, CustomerEntity et OrderEntity. Le client prépare l'objet de données et le transmet en un seul appel. C'est au service que revient la responsabilité de faire les mises à jour. Le nombre d'appels au serveur est réduit, et les données sont groupées : la granularité des appels a augmenté.

frères ennemis ?

Comme on peu le voir ci-dessus, le tout objet a ses limites. Contrairement à ce que l'on pourrait attendre, ces limites incluent jusqu'à la réutilisabilité. Dans le modèle tout objet, les couches sont intimement liées entre elles. En découplant les modules applicatifs en réduisant les liens entre eux par la suppression des appels directs entre objets de couches différentes, il devient plus facile de réutiliser ces modules.
Dans le modèle orienté objets, les couches sont également couplées temporellement, durant toute la durée de vie des objets. On peut considérer qu'un objet retourné par une couche inférieure est vivant tant qu'il est utilisé par la couche supérieure cliente. Cela ne doit pas être le cas dans une architecture orientée services, où les appels entre modules doivent supporter les modes asynchrone et déconnecté.
Pour autant, l'objet ne perd pas sa valeur. Mais c'est à l'intérieur de chaque couche de responsabilité que seront mis à profit la programmation orientée objets et les design patterns.

Rumeur : la SOA signe l'arrêt de mort de la POO.

En tout cas, c’est un message colporté par Don Box (responsable d'Indigo), à moins que cela ne soit le produit d'un journaliste en manque de titre accrocheur... Quand on trouve des articles intitulés "Don Box de Microsoft a déclaré que SOA éclipsera la programmation orientée objets", on comprend aisément qu'il y a de quoi semer la confusion et troubler les esprits.
Eh bien, soyons clairs : ce n'est pas vrai, la SOA ne remplacera pas la POO. Qu'il s'agisse d'une déformation journalistique ou d'une tentative marketing maladroite de Don Box, il est temps de dissiper les craintes et de clarifier le discours.

Opposer POO et SOA, ça me fait penser à la précédente annonce en fanfare par les journaliste du remplacement de la POO par l'AOP (la programmation par aspects). Un minimum de conscience professionnelle éviterait ce genre de débordement du genre « ça y est j’ai découvert la technologie du futur qui va tout remplacer ! ». Mais je m'égare...

D'ailleurs, on pourrait même envisager la SOA comme un retour vers la programmation orientée objets pure. Vous vous rappelez des bases théoriques sur les objets ? Comme quoi les objets échangent des messages entre eux lorsqu'ils s'appellent les uns les autres ? Ces préceptes avaient été mis de côté, en tout cas avec C++, Java et .NET. Eh bien il se pourrait bien que ce soit la SOA qui les ramène au goût du jour.

Complexité

Rumeur : en SOA, vos modules applicatifs communiquent par messages.

Eh bien, je pense qu'on peut faire une conception SOA sans le moindre message et appliquer une bonne partie des concepts SOA tout de même. Une fois de plus, vous n'avez pas à tout jeter pour repartir de zéro ni jeter aux oubliettes votre façon de raisonner actuelle.

Rumeur : on ne peut pas parler de SOA sans parler de processus métiers, d'orchestration et de transactions.

Pensez-vous réellement que vous applications soient devenues complexes à ce point du jour au lendemain ? Avez-vous besoin aujourd'hui de prendre en considération tous ces problèmes, adopter tous ces standards et apprendre tous ces langages complexes ?

Où en êtes vous aujourd'hui ?

Si vous ne suivez pas les sourates de la SOA, vos applications sont vouées à un destin tragique, vos architectes sont bons à brûler en enfer et vos chefs de projet condamnés aux travaux forcés pour rembourser les pertes gigantesques que votre entreprise accumulera d'ici peu !
Trêve de plaisanterie, vous avez encore un peu de temps devant vous et peut-être même faites-vous déjà partie des pionniers de la SOA sans le savoir.

Si vous basez vos développements sur une approche similaire à Duwamish Books 7, vous êtes déjà sur la bonne voie.
Duwamish est une application exemple de référence proposée par Microsoft. La mouture basée sur le framework .NET est livrée avec Visual Studio .NET.
 


Architecture de l'application Duwamish

La conception de l'application Duwamish date peut-être un peu, mais elle introduisait déjà des considérations que l'on retrouve dans la SOA. Vous remarquerez le découpage en couches, mais surtout l'utilisation de DataSets pour faire transiter les données entre les couches. On trouve ici avec les datasets l'introduction aux objets de données (business entity) sérialisables en XML et détachés de la source de données.

Voici en simplifié un schéma qui peut résumer la façon dont on peut concevoir une application .NET en intégrant le découpage classique en couches de responsabilité et la SOA :

Ce qu'on peut observer par rapport à ce schéma :

  • Les couches ne sont par fortement liées entre elles.
  • Les couches échangent des objets de données (DTO).
  • Les échanges sont courts, mais peut-être plus volumineux que dans le cas de l'approche objets.
  • Le module Common (assembly) contient les classes partagées entre toutes les couches, telles que les objets de données. Ceci n'étant valable uniquement si les couches sont implémentées avec la même technologie.
  • L'ensemble du développement repose sur un framework maison, pas uniquement sur le framework .NET ou J2EE.
  • La bibliothèque Controls contient les composants graphique utilisés par la couche Présentation.

Comme vous pouvez le voir en comparant les schémas, la SOA peut être mise en place progressivement car elle n'est pas diamétralement opposée à l'existant.

Mots-clefs, définitions et règles

Découplage

En SOA, le maître mot est "découplage". On retrouvera ce mot à différents niveaux. Voici par exemple trois objectifs que l'on cherche à atteindre dans le cadre de la SOA où l'on retrouve cette notion de découplage :

  • réduire le couplage entre modules (pour une meilleure réutilisabilité)

  • réduire le couplage vis à vis de l'infrastructure et de la plate-forme (pour une meilleure intéropérabilité)

  • réduire le couplage entre le client d'un service et une implémentation spécifique de ce service (pour une meilleure évolutivité)

Service

On le comprend aisément, le mot-clef dans SOA est service. Définir un service est un exercice difficile auquel plusieurs se sont déjà pliés. Je tenterai moi aussi ma chance en vous donnant ma définition :

"Un service est un module invocable chargé d'une fonction particulière et qui présente une interface bien définie."

Vous pouvez faire l'analogie avec les services d'un hôpital par exemple.

Il faut bien noter que le terme service a un sens plus large que simplement "service web". On peut faire de la SOA sans services web, et inversement mettre en oeuvre des services web ne signifie pas que l'on fait de la SOA. Les services web offre une solution technique pour la mise en place d'une SOA.
Il existe différents types de services. Un service peut être local ou distant. Exemples de services : service mis à disposition sur Internet avec SOAP et WSDL, base de données, annuaire, serveur de message queuing, etc.

Un service est créé dans le contexte d'une application (on crée rarement un service dans le néant), mais il doit être conçu de façon à pouvoir être utilisé dans d'autres contextes. On essayera par conséquent d'anticiper les utilisations ultérieures d'un service, et les contraintes associées.
De la même manière, il faut dès le départ concevoir ses services pour qu'ils puissent être utilisés aussi bien en local qu'à distance. Une adaptation tardive à un fonctionnement à distance demanderait une révision poussée. Le respect des règles de conception citées ci-dessous que sont la Façade et les Objets de Données assurent en grande partie une facilité d'évolution vers un mode distant.

Il va de soi que les applications et les services ne fonctionnent pas de la même manière suivant leur contexte d'utilisation. Par exemple, un service optimisé pour un fonctionnement en mode distant ne sera pas optimal pour un fonctionnement en mode local, et inversement.
Toute fois, il est possible de supporter les deux modes de fonctionnement. Si l'on prend simplement par exemple la signature des méthodes d'un service, il est possible de fournir deux versions, dont une permet d'optimiser les appels s'il se font dans un seul processus, et l'autre de distribuer physiquement les couches . Il est alors possible de passer en mode distant sans avoir à revenir sur le code.

Par exemple, là où on écrira ListCustomers(DataSet) pour un fonctionnement optimal en local, on écrira DataSet ListCustomers() pour un meilleur fonctionnement en mode distant. La première version permet de passer directement depuis la couche Présentation un DataSet à alimenter. Ceci n'est pas souhaitable à distance, puisque cela impliquerait de nombreux appels inter-processus ou inter-machines. La seconde version retourne donc un DataSet créé et alimenté par la méthode ListCustomers du service, ce DataSet étant ensuite sérialisé pour être retourné à l'appelant.

Factorisation

Un service doit assurer un rôle bien défini et non redondant.
Dans les schémas suivants, est exposé le cas d'un service qui requiert une authentification de l'appelant.

 
Service intégrant une gestion de l'authentification.

Il est préférable d'isoler le traitement d'authentification à l'extérieur du service. Ce traitement devrait faire lui-même l'objet de la création d'un service.


Après externalisation de la gestion de l'authentification

Par ce biais, le service ne remplit plus que son rôle fonctionnel, en se basant sur un service dont le rôle fonctionnel propre est l'authentification. On tire également des bénéfices de la factorisation des services, un second service pouvant à son tour utiliser le service d'authentification.
On évite également de dupliquer le code de gestion de l'authentification dans chaque service. On respecte le principe DRY (Don't Repeat Yourself) : "Every piece of knowledge must have a single, unambiguous, authoritative representation within a system".

Ce raisonnement rendra également service (hou, le méchant jeu de mots !) si l'on souhaite mettre en place en mécanisme de single sign-on (SSO). Une preuve du bien-fondé de l'opération s'il vous en fallait une.

Façade

La conception d’un module doit être orientée vers l’extérieur. Le concepteur doit se positionner du point de vue d’un utilisateur du module qui doit être conçu. Ce qui sera mis à la disposition d‘un utilisateur du module se nomme façade ou interface par opposition à l’implémentation qui est la partie purement des traitements.


Découpage d’un module métier

Simplification de l'utilisation

-> Simplifiez l’interface de vos modules métier

Un objectif important à atteindre est la simplification de l’interface qu’offre un module vers l’extérieur. Il faut s’appliquer à fournir une interface publique des modules n’obligeant pas à manipuler directement des objets, c’est pourquoi on passera par une façade.

Contrat de service

-> L’interface de vos modules symbolise le contrat qu'ils proposent

Un second objectif est de séparer le contrat de la réalisation. C'est ce qui permet de changer d'implémentation sans rompre le contrat. Une même interface peut être partagée par plusieurs implémentations. Les services deviennent alors interchangeables.
Le point de jonction entre un service et ses consommateurs est la façade du service. Dans ces conditions, il est plus aisé de remplacer un service par un service équivalent puisque le plus gros de la tâche consistera à rétablir le couplage entre fournisseurs et consommateurs.

Le modèle Façade

Le design pattern Façade unifie et simplifie l'interface d'un sous-système cohérent et éventuellement autonome. Une façade forme donc un point d'entrée simplifié dans une API. La façade permet en effet de limiter les points d'entrée d'une API, ce qui a comme effet bénéfique pour votre ensemble de classes, s'il est complexe, d'avoir une chance d'être utilisé.

On mettra en œuvre ce modèle en regroupant dans un objet l’ensemble des traitements proposés par un module applicatif, sous la forme d’une liste de méthodes, de manière à ce que ces méthodes ne soient pas disséminées dans différents objets.

Pratique souhaitable : commencez par définir les façades de vos modules métier avant de définir leur implémentation.

C'est d'autant plus facile qu'une façade peut se définir à partir de cas d'utilisation tels qu'on les rencontre en UML. On regroupera au sein d'une façade les traitements qui sont liés fonctionnellement, et cela peut mettre en jeu plusieurs objets métiers. D'ailleurs, lorsque vous définissez vos cas d'utilisation, raisonnez-vous à base d'objets métiers ou de cas d'utilisation ?

Bénéfice connexe : Comme l'indique le terme Remote Façade employé par Martin Fowler, le modèle façade est bénéfique en mode distant. En augmentant la granularité, on réduit le nombre d'appels, et on peut ainsi augmenter les performances.

Exemples de façade

Voici les méthodes que l'on pourrait rencontrer dans la façade sur service CustomerService :

CustomerData ListCustomers()
CustomerData ListCustomers(filter)
CustomerData GetCustomer(customerID)
void AddCustomers(CustomerData data)
void DeleteCustomer(customerID)
...

Pour la façade sur service OrderService :

OrderData ListOrders(customerID)
OrderData GetOrder(orderID)
void AddOrders(OrderData data)
void DeleteOrder(orderID)
...

Objet de données

Les objets de données ne contiennent pas de logique métier, uniquement des données. D'ailleurs, on peut les imaginer comme de simples structures de données destinées à faire transiter les données d'une couche à une autre. Bien sûr, il s'agit là d'une définition stricte qui peut (doit ?) comme toute autre être arrondie dans les angles. On s'autorisera donc parfois à adjoindre un comportement minimal à ces objets.

Les objets de données doivent respecter un ensemble de règles, parmi lesquelles :

  • être sérialisables en XML et structurés par un schéma XSD
  • être indépendants des plates-formes d'implémentation
    Un objet de données fourni par un service réalisé en Java doit pouvoir être consommé par une application réalisée en .NET par exemple. La sérialisation des objets de données en XML assure de ce point.
    Dans cet exemple, il y a du côté service un objet .NET et du côté client un objet Java qui sont deux incarnations d'un même schéma XML.
  • être indépendants de la source de données
    Le meilleure moyen pour cela étant qu'il ne contiennent pas le code de persistance

Plusieurs termes sont utilisés pour référencer les objets de données. Vous pourrez rencontrer Business Entity (entité métier), Value Object, ou encore Data Transfer Object (DTO).

Le terme Data Transfer Object à l'avantage de mettre en évidence qu'un objet de ce type ne contient qu'un agrégat de données destiné à être transféré et pas de logique métier.

L’objet DataSet fourni par la plate-forme .NET est un exemple d’objet de données respectant ces règles, c’est pourquoi son utilisation est recommandée.
Pour autant, n’est pas exclue l’utilisation de types scalaires tels que les entiers, les réels, les dates ou les chaînes de caractères. Tout objet de type "objet par valeur" (ValueType) tel qu’une structure (struct) ou qu’une énumération est également valide.
Il faut être prudent avec les DataSets. Les objets de données DataSets tels qu'ils sont sérialisés par défaut par .NET sont difficilement exploitables par J2EE. Il faut penser à avoir un format XML qui ne soit pas trop lié à une classe d'une plate-forme particulière.

Exemple d'objet de données

Voici à quoi peut ressembler l'objet de données OrderData représentant une commande :

   1  OrderHeader (OrderNo, CustID, OrderDate, ShipDate)
   1  Customer (CustID, Name)
1..n  Line (ProductID, Quantity)

Un objet de ce type permet de retourner en un seul appel l'ensemble des données d'une commande. On évite ainsi de faire un appel pour l'entête, un pour les informations sur le client et un pour les lignes de commande.
La signature d'une méthode retournant ce type de donnée serait comme ceci : OrderData GetOrder(id)

le modèle objet

De l'(in)adéquation entre SOA et les outils de mapping objet-relationnel

Une petite note finale pour vous mettre en garde par rapport aux frameworks de mapping objet-relationnel qui ne permettent pas de sérialiser les objets de données au format XML. Ils sont nombreux et sont bien souvent mal adaptés à une architecture orientée services.
Les outils de mapping objet-relationnel basent souvent vos développement sur le principe que les entités que vous manipulez sont liées à une source de données dans laquelle il viennent s'inscrire lorsqu'ils subissent des modifications. En SOA, la responsabilité de la persistance est déléguée à une couche particulière, le code de persistance ne se trouve en aucun cas dans l'entité elle-même.

Vous vous poserez au passage les questions suivantes :

  • Puis-je enregistrer mes objets de données vers différents formats ?
  • Est-ce que je maîtrise les appels qui sont faits pour la persistance ? Ces appels sont-ils fréquent ? Les moments où ils surviennent sont-ils bien définis ?
  • Est-ce que je peux exploiter mes objets de données depuis une autre plate-forme ? Sans l'outil de mapping objet-relationnel ?
  • Est-ce que mes objets métiers n'appelleraient pas directement la base de données depuis la couche présentation, par hasard ?
  • Que se passe t'il si je place ma couche de présentation ou les clients de mon service à distance ?

Pour aller plus loin

Certains trouveront probablement que j'ai donné une présentation de SOA non conventionnelle et simpliste. J'en suis fort aise, mon but étant effectivement d'éviter la complexité que l'on pourrait nous imposer.

J'ai volontairement laissé de côté invocations asynchrones, processus métiers, orchestration de services et sécurité, pour ne pas complexifier le message. Ce ne sont pas pour autant des points à négliger. Simplement, il est possible d'aborder ces points ultérieurement, sans se lancer dès maintenant dans des développements 100% pure SOA. Je vous recommande toutefois de vous intéresser à l'ensemble de ces points, d'une part pour savoir vers quoi on va, et d'autre part pour garder à l'esprit les futures contraintes auxquelles vos applications auront peut-être à se plier. Par exemple, il faut essayer de concevoir ses applications en imaginant qu'elles puissent fonctionner en mode asynchrone ou en mode déconnecté demain, même si ce n'est pas le cas dans l'immédiat.
De nombreux articles, outils et exemples sont d'ores et déjà présents pour vous permettre d'aborder ces sujets.

Voici quelques sujets auxquels vous pouvez vous intéresser pour aller plus loin :

  • Shadowfax, destinée a être la nouvelle application de référence de Microsoft. Son objectif est de présenter comment une solution SOA peut être mise en place aujourd'hui.
  • Indigo, l'infrastructure de communication entre applications à base de services web intégrée à Windows Longhorn (une version pour Windows XP et 2003 sera fournie), mais que vous ne déploierez probablement pas avant quelques années... A suivre de loin tout de même.
  • Ce qui tourne autour de BPM (Business Process Management) et BPEL (Business Process Execution Language)
  • Biztalk et les produits similaires pour l'orchestration des processus métiers.

Epilogue

Si je devais fournir une conclusion, je répéterais simplement que vous ne devriez pas hésiter à adapter la SOA à la réalité de vos applications encore plus que l'inverse. Les belles théories sont faites pour guider, pas pour être des carcans.


Qui est Fabrice Marguerie ?
Fabrice Marguerie est architecte .NET chez Masterline. Fabrice intervient sur des missions de conseil, de conception ou de réalisation. Il a conçu et réalisé le framework .NET de Masterline.
Fabrice rédige un weblog en anglais : http://weblogs.asp.net/fmarguerie et gère le site http://SharpToolbox.com

Sa société : Masterline
Créée en 1989, Masterline est une SSII qui développe son expertise autour de trois marchés : business intelligence, e-business, SAP. L'accompagnement de Masterline prend la forme de prestations de conseil en technologies, d'ingénierie et services et d'externalisation, conçues et conduites avec pour objectif premier la création de valeur pour le client. Masterline développe ses expertises (.NET, Java, objet et UML, etc.) au sein de centres de compétences dédiés. Masterline est partenaire Microsoft depuis 1994.

Ressources

Shadowfax : http://workspaces.gotdotnet.com/shadowfx

PetshopSOA : http://dotnetguru.org/article.php?sid=286

Duwamish : Documentation - Présentation Powerpoint

Udi Dahan : sur le weblog de Udi Dahan, vous trouverez des entrées que je vous conseille en complément :
http://udidahan.weblogs.us/archives/012683.html - I'll see you when you get there
http://udidahan.weblogs.us/archives/012770.html - But that trick never works dans lequel il conseille SOA pour les nouveaux développements, pas nécessairement pour les existants

15 seconds - Realizing a Service-Oriented Architecture with .NET : une introduction orientée services web, mais simple et efficace, http://www.15seconds.com/issue/031215.htm

The Pragmatic Programmer : si ce n'est pas encore votre livre de chevet, procurez-vous le immédiatement ! A lire et à relire. Le chapitre 5 "Bend, or Break" parle de SOA alors que le terme n'était pas encore employé. Les auteurs de ce livre ont également un site web : http://www.pragmaticprogrammer.com