Architecture N-Tier, kézako?

Dans la description de mon blog j’avais promis de partager quelques informations sur la conception. Voici donc un premier article sur ce qu’on appelle une architecture n-tier.

Au delà de la programmation objet et des design patterns il existe une autre dimension qui est celle de l’architecture d’un logiciel. Cette architecture est en fait une manière de segmenter une application en plusieurs blocs ou couches (le N dans N-tier fait référence au nombre de couches) plus ou moins indépendants qui communiquent entre eux par le biais d’interfaces et d’objets de transfert.

Pour cet article je vais me limiter au genre d’architecture initialement vu lors d’une formation avec John Rizzo de BlackBeltFactory.

L’application de base peut être segmenté de la manière suivante:

– Data Access Layer (DAL).
– Business Logic Layer (BLL).
– User Interface (UI).

Le Data Access Layer est la couche responsable de la communication avec la source de données. Celle-ci peut être une base de données SQL, des fichiers XML et même un ensemble de fichier plats. L’idée est d’ajouter une couche d’abstraction de sorte que le reste du logiciel communique avec la DAL et pas directement avec la source de données.

Le Business Logic Layer, lui, forme le coeur du logiciel et englobe tous les processus qui vont manipuler et transformer les données dites business définies dans le demande client.

Le User Interface comprend tout ce qui est affichage et interaction avec l’application.

Il est important de noter que la communication entre ces couches doit se faire de manière successive allant de la DAL jusqu’au UI. En aucun cas le BLL devrait pouvoir communiquer directement avec la source de données. Même chose pour le UI qui ne peut communquer directement avec le DAL. Ce principe combiné avec la programmation dite contre interface garanti qu’une modification dans une couche n’impose aucun changement dans les autres.

Nous allons encore nuancer cette segmentation avec des packages style Java selon l’approche dite Domain-Driven Design (DDD):

– dao
– dao.impl
– domain
– services
– services.impl
– utilities
– resources
– constant
– ui
(- jsf)

Le package domain comprend toutes les classes modélisant le domaine étudié. Ceci comprend des classes conteneurs qualifié de « domain objects » (DO). Selon le domaine on peut retrouver des noms comme User, BankAccount et Article avec des références en attribut pour représenter des liens 1 à 1, 1 à N et N à N entre objets. Les classes peuvent être anémiques (attributs + getters/setters) ou riches (méthodes supplémentaires). Personellement, je préfère l’anémique car il éviterait certaines dépendances.

Le package dao est équivalent au DAL et regroupe des classes utilisant le pattern Data Access Object défini par Sun. Ce pattern permet de transposer les informations tirées d’une source de données sous forme de DO. Le package dao comprend des définitions d’interfaces qui reprennent des méthodes CRUD (Create-Read-Update-Delete). Les interfaces permettent d’établir un contrat qui sera appliqué aux différentes classes DAO selon le DO associé ce qui rend plusieurs implémentations selon le type de source de données (SQL, XML, …) ou le framework utilisé (Hibernate, iBatis, …) que l’on retrouve dans le package impl. Il peut être intéressant d’écrire un Data Access Object générique d’où toutes les implémentations pourront découler.

Les classes services, elles, correspondent à la business logic. On peut distinguer trois types de classes services:

– Domain Services.
– Application Services.
– Infrastructure Services

Les services domaine encapsulent des méthodes de style non-CRUD qui n’ont pas vraiment leur place dans les domain objects. Par exemple, une classe BankAccount ne devrait pas modifier l’ensemble des comptes en banque et il serait plus sensé de déléguer cette tâche à une classe BankService.

Les services application sont utilisés par des consommateurs externes pour dialoguer avec le système, un exemple étant les Web Services. Il est tout à fait possible à ce niveau d’exposer des opérations CRUD qui communiquerons avec les couches inférieures. Les services d’infrastructures sont utilisés comme abstractions pour des questions techniques comme la gestion d’un fournisseur email.

Le package ui regroupe bien évidemment les classes qui servirons pour l’interaction homme machine (ex: des classes Swing). Les accès s’y font exclusivement à travers des méthodes de classes services ce qui permet une écriture plus concise mais nécessiterais une modélisation supplémentaire dans le UI dans le cas où il est nécessaire de composer des informations (ex: affichage de données tirées d’un DO avec un flag de validation).

A ce niveau il est intéressant de noter que des variantes du pattern MVC peuvent être appliquées. Dans le contexte d’une application web on pourrait remplacer le package par un package jsf (framework Faces) mais dans ce cas les beans jouent le role de controlleur tout comme le feraient des servlets avec les pages formant le View à proprement parler.

A cela on peut ajouter les derniers packages un peu plus fourre-tout. Le package utilities regroupe des classes contenant des méthodes exclusivement statiques (manipulation de String, dates, …), sans état et qui sont tout à fait indépendantes du domaine. Le package constant contient des classes avec des valeurs constantes codées en dure ou des enumérations et le package resources est bien souvent utilisé pour contenir des fichiers properties ou de configuration genre applicationContext.xml (framework Spring).

En espérant que cela rende plus claire le concepte d’architecture je vous invite à poster des commentaires si vous avez des précisions ou informations à ajouter au sujet.

– James Poulson.

P.S: Une architecture peut être appliqué dans d’autres langages comme le PHP. Il y a toutefois des divergences quant aux solutions à utiliser.

5 réflexions au sujet de « Architecture N-Tier, kézako? »

  1. @Radwane: Tu fais bien de le souligner. Il y a un débat à ce sujet dans le sens où un domaine anémique n’est pas conforme à l’idéal objet. C’est d’ailleurs l’une des raisons pour lesquelles Martin Fowler est réfractaire à cette approche. Elle est toutefois encouragé par les Entity J2EE comme il le précise.

    En pratique, la difficulté d’implémenter un domaine riche vient du fait qu’il est nécessaire d’établir un compromis pour décider quelles méthodes devraient rester dans le domaine. C’est un point sur lequel Fowler et King seraient d’accord.

    Les deux aspects sur lesquels il est nécessaire de veiller lorsqu’on a un domaine riche sont les dépendances et l’exposition (interface). Pour la transition d’une méthode vers la couche service je dirais que cela se justifie si celle-ci doit interagir avec plusieurs DO. Cela évite que du code se retrouve parsemé à travers le domaine. Finalement, il est important de rendre compte que des problèmes de concurrence de threads peuvent affecter le domaine.

    Il y a un sujet intéressant sur SO à ce propos:
    http://stackoverflow.com/questions/2333307/should-enterprise-java-entities-be-dumb/

  2. @eric190: C’est pour cela que j’en parle ici. Le concepte est un peu flou et j’espère pouvoir le raffiner pour en faire un article.

    Les services domain peuvent être considérés comme une couche supplémentaire et semblent correspondre avec l’idée de process. Il s’agit d’instances comme les DAO regroupant des méthodes formant des genres de boite à outils pour les classes domain (ex: UserService: login, updateInfo, addFriend,…). Dans un contexte anémique on peut y trouver une bonne partie de la logique d’une application.

    P.S: Je ne connais par l’origine de la terminologie mais le mot service est utilisé dans Spring (annotation @Service) ainsi qu’au niveau de cette méthodologie: http://programmers.stackexchange.com/questions/49749/uml-going-from-use-case-to-class-diagram/49750#49750

  3. Bonjour,

    Intéressant ton billet, d’autant que c’est rare de voir cette thématique (architecture logicielle) vulgarisée.
    Peux tu expliciter les services domain ? Est-ce bien dans le cadre de la couche Business ?

    Merci

    @+

Les commentaires sont fermés.