EJB et « séparation des préoccupations », mythe ou réalité


Avant de s'étendre sur le coeur de la problématique, il serait utile de définir ce néo-barbarisme "franglais" qu'est l'expression "séparation des préoccupations".

La séparation des préoccupations, qu'est ce que c'est ?

Il s'agit de la capacité d'une application ou d'un système à isoler dans des composants ou modules distincts les différentes problématiques qu'elle doit traiter. Ainsi, la séparation claire des préoccupations d'ordre métier (services métiers, règles de gestion, etc ...) des préoccupations d'ordre technique (gestion des transactions, de la sécurité, de la scalabilité, de la traçabilité) permet de garantir l'évolutivité indépendante des composants et évite que le code soit inutilement dupliquer en leur sein.

Il s'agit là encore d'une simple définition, car dans la pratique certaines préoccupations d'ordre technique telle que la gestion des transactions par exemple ne peuvent être isolées dans un unique composant indépendant des autres. Le système aussi modulaire qu'il puisse être se voit très vite contraint par le besoin de "centralisation" de ces problématiques. On parle ici de centralisation en plus de la modularité, car même si les composants peuvent exister indépendamment les uns des autres, un (ou plusieurs) d'entre eux devra être couplé avec une partie (ou l'ensemble) des autres afin d'y traiter les problématiques transverses pour lesquelles il est voué.

Dans notre cas, il s'agirait par exemple de centraliser la gestion de la persistance dans un composant et de le coupler (le plus faiblement possible) aux composants hébergeant la logique métier et la supervision applicative. Une des réponses (sinon la seule) proposée par J2EE pour gérer cette problématique est la spécification EJB (Enterprise Java Beans) et le conteneur EJB embarqué dans tout serveur d'applications reconnu.

Comment la spécification EJB propose de garantir la séparation des préoccupations ?

Nul besoin de s'étendre sur la définition des différents types d'EJB (Entité, Session, Message), mais de rappeler que les EJB sont des objets java déployés sur le serveur d'applications et dont le cycle de vie est intrinsèquement géré par le conteneur. Les EJB sessions par exemple, dont le rôle est d'implémenter les traitements selon un mode conversationnel (avec ou sans état) avec un client, peuvent héberger l'ensemble de la logique applicative propre au cas d'utilisation (règles métiers, accès aux bases, transcodifications, etc ...) et déléguer certaines préoccupations transverses au conteneur. Celui-ci en lisant le paramétrage contenu dans les descripteurs de déploiement de l'EJB (dans notre cas le fichier ejb-jar.xml) peut intercepter les appels des clients (locaux ou distants) et effectuer une ou plusieurs des actions suivantes :

  • Rendre transactionnelle (en récupérant ou propageant un contexte transactionnel via la norme JTA) l'implémentation des traitements, de sorte que les appels à toutes ressources transactionnelles (SGBDR, Provider JMS, etc ...) soient tous acquittés ou tous abandonnés.
  • Gérer le nombre initial et maximum d'instances de l'objet dans le pool du serveur
  • Gérer les restrictions d'accès sur les méthodes métiers de l'objet
  • etc ...

Ainsi le développeur s'astreint de l'écueil fastidieux de ces préoccupations d'ordre technique qui en plus d'être sources d'erreurs de programmation font perdre le temps de leur écriture et se couplent fortement avec une problématique d'ordre différent qui est la logique métier. J2EE répond donc à la problématique de séparation des préoccupations en faisant gérer les préoccupations techniques transverses par le serveur d'applications lui-même, ce qui a du sens, mais alourdit considérablement les responsabilités du serveur au sein de l'architecture applicative. Ces serveurs généralement commercialisés par des éditeurs de type BEA (Oracle), IBM, Borland, SoftWare AG ou en open source (JBOSS,JONAS, etc ...) ont des implémentations différentes des spécifications J2EE, ce qui peut poser un problème de portabilité d'une solution d'un serveur à l'autre. Et si la limite était induite par le serveur d'applications lui-même ?

C'est par là que les bactéries attaquent !!!

Nous venons de le dire, la norme J2EE impose l'omniprésence d'un composant technique lourd qu'est le serveur d'applications. Pour les EJB de type Entité, dont le rôle est d'assurer le mapping entre les propriétés des objets java et leur support de persistance, la situation s'est détériorée davantage, car en plus du serveur d'applications, ces composants ne peuvent exister indépendamment du support (base de données relationnelle en général). La réutilisation dans un contexte technique différente est ainsi compromise.

La testabilité unitaire du code applicatif et en particulier de la logique métier (faisant partie des bonnes pratiques de développement Java ) est difficile dans un contexte autant couplé avec l'architecture technique.Ceci empêche de se focaliser sur une seule et unique préoccupation à la fois. D'autre part, en plus de ne pas être toujours portable d'un serveur d'applications à l'autre, la logique applicative n'est pas facilement portable entre les différentes versions des spécifications EJB non plus. Ainsi des EJB 2.0 nécessiteront une ré-écriture pour tirer tous les avantages des nouvelles fonctionnalités liées à la norme 3.0.

Côté client, la technologie EJB est particulièrement lourde. Les classes clientes doivent être écrites en java et se doter de traitements techniques spécifiques pour accéder aux EJB. Ces traitements (initialisation d'un contexte, recherche d'objets dans l'arbre JNDI distant, instanciation distante des objets dans le conteneur) même s'ils sont optimisés par certains pattern J2EE (Service locator, Business Delegate, ...) sont coûteux en trafic réseau et en ressources. On peut remarquer que la norme EJB 3.0 évite ce genre d'écueils pour les appels locaux d'EJB, c'est-à-dire pour les appels d'EJB gérés par la même machine virtuelle.

Et alors ?

Toutes ces contraintes ont poussé à un modèle de programmation radicalement différent et à l'avènement du framework Spring basé sur l'injection de dépendances et sur les POJO (plain od java objects). Spring offre une alternative aux EJB en se basant sur un conteneur "léger" hébergeant les "factory de beans" interdépendants. S'agit-il cependant d'une réelle alternative ? De par sa richesse, les projets ont tendance à utiliser Spring comme le framework à tout faire, sans se concentrer sur les spécificités du contexte applicatif. Un prochain post détaillera ces différentes problématiques...

Contactez-nous

42 rue de Maubeuge
75009 Paris

Suivez-nous

Tous textes sous licence Creatice Commons CC-BY - Mentions légales Licence Creative Commons