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.
|