66 votes

Décrivez l'architecture que vous utilisez pour les applications web Java ?

Partageons les architectures d'applications web basées sur Java !

Il existe de nombreuses architectures différentes pour les applications web qui doivent être mises en œuvre à l'aide de Java. Les réponses à cette question peuvent servir de bibliothèque des différentes conceptions d'applications Web avec leurs avantages et inconvénients. Bien que je réalise que les réponses seront subjectives, essayons d'être aussi objectifs que possible et de motiver les avantages et les inconvénients que nous énumérons.

Utilisez le niveau de détail que vous préférez pour décrire votre architecture. Pour que votre réponse ait une quelconque valeur, vous devrez au moins décrire les principales technologies et idées utilisées dans l'architecture que vous décrivez. Et enfin, le plus important, quand devons-nous utiliser votre architecture ?

Je vais commencer...


Aperçu de l'architecture

Nous utilisons une architecture à trois niveaux basée sur les normes ouvertes de Sun comme Java EE, Java Persistence API, Servlet et Java Server Pages.

  • Persistance
  • Entreprise
  • Présentation

Les flux de communication possibles entre les couches sont représentés par :

Persistence <-> Business <-> Presentation

Ce qui signifie par exemple que la couche de présentation n'appelle ou n'effectue jamais d'opérations de persistance, elle le fait toujours par le biais de la couche métier. Cette architecture est destinée à répondre aux exigences d'une application web à haute disponibilité.

Persistance

Effectue la création, la lecture, la mise à jour et la suppression ( CRUD ) des opérations de persistance. Dans notre cas, nous utilisons ( API de persistance Java ) JPA et nous utilisons actuellement Hibernate comme fournisseur de persistance et utiliser son EntityManager .

Cette couche est divisée en plusieurs classes, chaque classe traitant un certain type d'entités (par exemple, les entités liées à un panier d'achat peuvent être traitées par une seule classe de persistance). utilisé par un et un seul manager .

En outre, cette couche stocke également Entités de l'APP qui sont des choses comme Account , ShoppingCart etc.

Entreprise

Toute la logique qui est liée à la fonctionnalité de l'application web se trouve dans cette couche. Cette fonctionnalité peut consister à initier un transfert d'argent pour un client qui souhaite payer un produit en ligne à l'aide de sa carte de crédit. Il peut tout aussi bien s'agir de créer un nouvel utilisateur, de supprimer un utilisateur ou de calculer l'issue d'une bataille dans un jeu en ligne.

Cette couche est divisée en plusieurs classes et chacune de ces classes est annotée avec @Stateless pour devenir un Haricot de session apatride (SLSB). Chaque SLSB est appelé un manager et par exemple, un gestionnaire pourrait être une classe annotée comme mentionné appelée AccountManager .

Lorsque AccountManager a besoin d'effectuer des opérations CRUD, il fait les appels appropriés à une instance de AccountManagerPersistence qui est une classe de la couche de persistance. Une ébauche de deux méthodes dans AccountManager pourrait être :

...
public void makeExpiredAccountsInactive() {
    AccountManagerPersistence amp = new AccountManagerPersistence(...)
    // Calls persistence layer
    List<Account> expiredAccounts = amp.getAllExpiredAccounts();
    for(Account account : expiredAccounts) {
        this.makeAccountInactive(account)
    }
}
public void makeAccountInactive(Account account) {
    AccountManagerPersistence amp = new AccountManagerPersistence(...)
    account.deactivate();
    amp.storeUpdatedAccount(account); // Calls persistence layer
}

Nous utilisons transactions du gestionnaire de conteneurs pour qu'on n'ait pas à faire la démarcation des transactions entre nous. Ce qui se passe essentiellement sous le capot, c'est que nous lançons une transaction lorsque nous entrons dans la méthode SLSB et que nous la validons (ou la rétablissons) immédiatement avant de quitter la méthode. C'est un exemple de convention par rapport à la configuration, mais nous n'avons pas encore eu besoin d'autre chose que la valeur par défaut, Required, pour le moment.

Voici comment The Java EE 5 Tutorial de Sun explique le processus d'intégration. Attribut de transaction requis pour les Enterprise JavaBeans (EJB's) :

Si le client s'exécute dans une transaction et invoque la méthode de l'enterprise la méthode du haricot d'entreprise, la méthode s'exécute dans la transaction du client. Si le client n'est pas associé à une transaction, le conteneur démarre une nouvelle transaction avant d'exécuter la méthode.

L'attribut Required est l'attribut de transaction implicite implicite de la transaction pour toutes les méthodes de haricot d'entreprise exécutées avec transaction gérée par le conteneur géré par le conteneur. En général, vous ne définissez pas l'attribut Required, sauf si vous devez pour remplacer un autre attribut de la transaction. Les attributs de transaction sont déclaratifs, vous pouvez facilement facilement les modifier ultérieurement.

Présentation

Notre couche de présentation est en charge de... la présentation ! Elle est responsable de l'interface utilisateur et montre les informations à l'utilisateur en construisant des pages HTML et en recevant les entrées de l'utilisateur par des requêtes GET et POST. Nous utilisons actuellement l'ancien Servlet + Java Server Pages ( JSP ) combinaison.

La couche appelle des méthodes dans gestionnaires de la couche métier pour effectuer les opérations demandées par l'utilisateur et pour recevoir les informations à afficher dans la page web. Parfois, les informations reçues de la couche métier sont des types moins complexes comme String et int egers, et à d'autres moments Entités de l'APP .

Avantages et inconvénients de l'architecture

Pour

  • Le fait d'avoir tout ce qui est lié à une façon spécifique de faire de la persistance dans cette couche signifie seulement que nous pouvons passer de l'utilisation de JPA à autre chose, sans avoir à réécrire quoi que ce soit dans la couche métier.
  • Il est facile pour nous de remplacer notre couche de présentation par une autre, et il est probable que nous le ferons si nous trouvons quelque chose de mieux.
  • Laisser le conteneur EJB gérer les limites des transactions est une bonne chose.
  • L'utilisation de Servlet + JPA est facile (pour commencer) et les technologies sont largement utilisées et mises en œuvre dans de nombreux serveurs.
  • L'utilisation de Java EE est censée nous permettre de créer plus facilement un système à haute disponibilité avec équilibrage des charges et basculer . Tous deux nous semblent indispensables.

Cons

  • Avec JPA, vous pouvez stocker les requêtes souvent utilisées sous forme de requêtes nommées en utilisant la fonction @NamedQuery sur la classe d'entité JPA. Si vous avez autant de choses que possible liées à la persistance dans les classes de persistance, comme dans notre architecture, cela répartira les endroits où vous pouvez trouver des requêtes pour inclure également les entités JPA. Il sera plus difficile d'avoir une vue d'ensemble des opérations de persistance et donc plus difficile à maintenir.
  • Nous avons des entités JPA dans le cadre de notre couche de persistance. Mais Account et ShoppingCart Mais si l'on veut que les classes de JPA soient utilisées, ne s'agit-il pas d'objets métier ? C'est ainsi que cela se passe, car vous devez toucher ces classes et les transformer en entités que JPA sait gérer.
  • Les entités JPA, qui sont aussi nos objets d'entreprise, sont créées comme des objets de transfert de données ( DTO ), également appelés objets de valeur (VO). Il en résulte un modèle de domaine anémique car les objets métier n'ont pas de logique propre, à l'exception des méthodes d'accès. Toute la logique est effectuée par nos gestionnaires dans la couche métier, ce qui donne lieu à un style de programmation plus procédural. Ce n'est pas une bonne conception orientée objet, mais ce n'est peut-être pas un problème ? (Après tout l'orientation objet n'est pas le seul paradigme de programmation qui a donné des résultats).
  • L'utilisation d'EJB et de Java EE introduit un peu de complexité. Et nous ne pouvons pas utiliser uniquement Tomcat (l'ajout d'un micro-conteneur EJB n'est pas un problème pour nous). purement Tomcat).
  • L'utilisation de Servlet + JPA pose de nombreux problèmes. Utilisez Google pour obtenir plus d'informations sur ces questions.
  • Comme les transactions sont fermées à la sortie de la couche métier, nous ne pouvons pas charger d'informations à partir des entités JPA qui sont configurées pour être chargées à partir de la base de données lorsqu'elles sont nécessaires (à l'aide de la fonction fetch=FetchType.LAZY ) depuis l'intérieur de la couche de présentation. Cela déclenchera une exception. Avant de retourner une entité contenant ce type de champs, nous devons nous assurer d'appeler les getter's appropriés. Une autre option consiste à utiliser le Java Persistence Query Language ( JPQL ) et faire un FETCH JOIN . Cependant, ces deux options sont un peu lourdes.

9voto

Rakesh Waghela Points 780

Les technologies de développement Web basées sur Java idéales aujourd'hui.

Couche Web :

HTML+CSS+Ajax+JQuery

Contrôleur Web RESTFul/Couche de traitement des actions/requêtes :

Cadre de jeu

Logique d'entreprise/couche de service :

Utilisez du code Java pur aussi longtemps que possible. On peut faire la fusion de services web ici.

Couche de transformation des données XML/JSon :

XMLTool(Search On Google Code),JSoup,Google GSon,XStream,JOOX (Search On Google Code)

Couche de persistance :

CRUD : JPA ou SienaProject ou QueryDSL / Requêtes complexes : JOOQ,QueryDSL

8voto

Rolf Points 2966

Ok, je vais en faire un (plus court) :

  • Frontend : Tapestry (3 pour les anciens projets, 5 pour les plus récents)
  • Couche commerciale : Spring
  • DAO's : Ibatis
  • Base de données : Oracle

Nous utilisons le support transactionnel de Sping, et démarrons les transactions dès l'entrée dans la couche service, en les propageant jusqu'aux appels DAO. La couche service a la plus grande connaissance du modèle d'entreprise, et les DAO font un travail CRUD relativement simple.

Certaines requêtes plus complexes sont traitées par des requêtes plus complexes dans le backend pour des raisons de performance.

L'avantage d'utiliser Spring dans notre cas est que nous pouvons avoir des instances dépendant du pays/de la langue, qui sont derrière une classe Spring Proxy. En fonction de l'utilisateur dans la session, l'implémentation correcte du pays/de la langue est utilisée lors de l'appel.

La gestion des transactions est presque transparente, le retour en arrière sur les exceptions d'exécution. Nous utilisons des exceptions non vérifiées autant que possible. Nous avions l'habitude d'utiliser des exceptions vérifiées, mais avec l'introduction de Spring, je vois les avantages des exceptions non vérifiées, en ne traitant les exceptions que lorsque c'est possible. Cela permet d'éviter un grand nombre d'expressions passe-partout du type "catch/rethrow" ou "throws".

Désolé, c'est plus court que votre message, j'espère que vous trouverez cela intéressant...

3voto

Dan Points 2609

Nous utilisons toujours la pile habituelle Struts-Spring-Hibernate.

Pour les applications futures, nous envisageons Spring Web Flow + Spring MVC + Hibernate ou Spring + Hibernate + Web Services avec un front-end Flex.

Une caractéristique distincte de notre architecture est la modularisation. Nous avons un certain nombre de modules, certains commençant avec 3 à 30 tables maximum dans la base de données. La plupart des modules se composent d'un projet commercial et d'un projet Web. Le projet commercial contient la logique commerciale et de persistance, tandis que le projet web contient la logique de présentation.
Au niveau logique, il y a trois couches : Business, Persistance et Présentation.
Dépendances :
La présentation dépend des affaires et de la persistance.
La persistance dépend des affaires.
Les affaires ne dépendent pas des autres couches.

La plupart des projets d'entreprise comportent trois types d'interfaces (remarque : il ne s'agit pas d'une interface graphique, mais d'une couche d'interface java programmatique).

  1. Interface que la présentation utilise comme client
  2. Interface que les autres modules utilisent lorsqu'ils sont le client du module.
  3. Interface qui peut être utilisée à des fins d'administration du module.

Souvent, 1 étend 2. De cette façon, il est facile de remplacer une implémentation du module par une autre. Cela nous aide à nous adapter à différents clients et à nous intégrer plus facilement. Certains clients n'achètent que certains modules et nous devons intégrer les fonctionnalités dont ils disposent déjà. Comme les couches d'interface et d'implémentation sont séparées, il est facile de déployer une implémentation de module ad-hock pour ce client spécifique sans affecter les modules dépendants. Et Spring Framework permet d'injecter facilement différentes implémentations.

Notre couche métier est basée sur des POJO. Une tendance que j'observe est que ces POJOs ressemblent à des DTOs. Nous souffrons de un modèle de domaine anémique . Je ne suis pas tout à fait sûr de la raison pour laquelle cela se produit, mais cela peut être dû à la simplicité du domaine de problèmes de beaucoup de nos modules, la plupart du travail étant du CRUD, ou au fait que les développeurs préfèrent placer la logique ailleurs.

1voto

joshua Points 1631

IMHO, la plupart d'entre nous ont un dénominateur commun. Au moins dans le back-end, nous avons une certaine forme de conteneur IOC/DI et un cadre de persistance. Personnellement, j'utilise Guice et Mybatis pour cela. Les différences se situent au niveau de l'implémentation de la couche vue/UI/présentation. Il y a deux grandes options ici (il peut y en avoir d'autres) : basée sur l'action (URLs mappés aux contrôleurs) et basée sur les composants. Actuellement, j'utilise la couche de présentation basée sur les composants (en utilisant Wicket). Elle imite parfaitement un environnement de bureau où j'utilise des composants et des événements plutôt que des URL et des contrôleurs. Je cherche actuellement une raison pour laquelle je devrais migrer vers ce type d'architecture URL-contrôleur (c'est ainsi que j'ai atterri sur cette page). Pourquoi tout ce battage autour des architectures RESTful et Stateless ?

Pour répondre brièvement à cette question : j'écris des applications web avec état en utilisant un cadre orienté composant au-dessus du conteneur Guice IOC et je place les données dans une base de données relationnelle en utilisant Mybatis.

0voto

nsfyn55 Points 4753

J'ai travaillé sur des projets qui utilisent ce modèle de gestionnaire rigide. Historiquement, j'étais un grand partisan de la hiérarchie rigide où tout rentrait dans une boîte bien rangée. Au fur et à mesure que je progresse dans ma carrière, je trouve qu'elle est souvent forcée. Je pense que l'adoption d'un état d'esprit plus agile à l'égard de la conception d'applications permet d'obtenir un meilleur produit. Ce que je veux dire par là, c'est qu'il faut créer un ensemble de classes qui résolvent le problème à résoudre. Plutôt que de dire "Avez-vous construit un gestionnaire pour ceci et cela ?"

Le projet sur lequel je travaille actuellement est une application web avec une combinaison de Spring MVC et d'appels JSON/Ajax RestEasy. Côté serveur, intégré dans nos contrôleurs, il y a un niveau de données basé sur une façade sensible avec JPA/Hibernate pour l'accès direct à la base de données, quelques accès EJB, et quelques appels de services web basés sur SOAP. Le tout est relié par un code de contrôleur Java personnalisé qui détermine ce qui doit être sérialisé en JSON et renvoyé au client.

Nous ne passons presque pas de temps à essayer de créer un modèle unifié, mais nous choisissons plutôt d'adopter l'idée "Worse is Better" de la philosophie de conception Unix. Il est en effet préférable de sortir des sentiers battus et de construire rapidement quelque chose de sensé plutôt que de construire quelque chose qui adhère à un ensemble de mandats de conception stricts.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X