[JAVA] Gestion des dépendances dans une architecture en couches

Quelle est cette page?

Cette page organise les méthodes de gestion de la logique métier introduites dans le nouveau projet. Comment structurer et utiliser des classes associées dans la situation où "vous n'avez pas besoin d'un énorme conteneur DI pour l'API Web comme Spring"? Est le point focal.

supposition

Ce projet était une simple bibliothèque commune qui renvoyait des résultats lorsqu'un argument était passé à une seule méthode qui devenait le point d'entrée. Dès le point d'entrée, la logique métier associée à plusieurs entités est définie (une architecture dite MVC).

Lorsque des modifications sont apportées à la logique métier, nous avons considéré cette fois-ci en supposant que le nombre de services qui ont une logique métier au lieu du point d'entrée augmentera ou changera.

C'est un peu désagréable pour l'appelant de créer et d'exécuter directement une instance du service

La classe de couche de service référencée à partir du point d'entrée est de 4 ou 5 au maximum, vous pouvez donc créer une instance directement ...

  1. S'il est nécessaire de créer une instance à partir de la classe. Est-il généré même s'il n'a pas d'état? Je pense même qu'il est normal de le pousser dans le contexte statique ultime.
  2. Le besoin d'une interface. Est-il seulement nécessaire de le mettre en œuvre? D'un autre côté, il est prudent de faire une FI comme promesse.
  3. Il existe environ trois façons d'appeler l'appelant. Génération d'instance, DI, méthode statique (utilisation). Et ainsi de suite, j'ai dû affronter la méthode de gestion des dépendances.

Peur, risque assumé, perspective

Je l'ai envisagé sous quatre angles:

  1. La logique métier est mise à jour lors du développement futur de fonctionnalités supplémentaires.
  2. S'appuyant sur des bibliothèques de matières grasses pour les conteneurs DI.
  3. Je ne veux pas prendre la peine d'installer la bibliothèque Spring / DI ... Il y a au plus 5 services. Un couplage serré se produit.
  4. Peut-il être lu simplement lorsque d'autres le lisent? Dans le passé, j'ai réfléchi au fait que je n'avais pas réussi à configurer la classe et que j'avais développé des fonctions compliquées que je ne pouvais pas voir, j'ai donc choisi avec soin.

Solution

J'ai décidé de préparer un simple conteneur DI. C'est une image d'une classe avec une telle structure entre la méthode de fabrique, le singleton et le localisateur de service. La classe de fabrique elle-même doit être une seule instance et les services doivent être récupérés à partir de cette seule instance.

Assurez-vous également que les mises à jour de la logique métier ne sont affectées que via l'usine. Lorsque la logique métier a été ajoutée, je me suis demandé s'il serait possible d'ajouter une méthode d'instanciation à l'usine.

Ensuite, la classe de couche supérieure qui dépend du service génère le service à partir de l'usine et l'utilise. La DI basée sur les annotations comme celle de Spring et Java EE semble un peu exagérée dans ce projet, je ne l'ai donc pas utilisée dans ce projet. À la suite de diverses enquêtes, j'ai adopté un modèle appelé DYDI (Do it Yourself Dependency Injection), qui est facile à préparer par moi-même et semble convenir à un projet compact comme celui-ci.

Image de mise en œuvre

Il se compose de trois classes: une classe qui génère la logique, une interface / implémentation de logique et un appelant.

Tout d'abord, préparez une classe de fabrique qui renvoie une instance avec logique.

ServiceFactory.java


public class ServiceFactory {

    /**
     *Instance unique spécifique à l'usine.
     */
    private static final ServiceFactory serviceFactory = new ServiceFactory();

    private ServiceFactory() {}

    public static ServiceFactory getInstance() { return serviceFactory; }

    /**
     *Renvoie la logique réelle.
     */
    public TargetLogic getTargetLogic() {
        return new TargetLogicImpl();
    }

Définissez l'interface et la logique renvoyées par cette usine. C'est un moyen rapide de le définir de manière flexible en fonction du cas d'utilisation.

TargetLogic.java


public interface TargetLogic {

    void consume();

}

TargetLogicImpl.java


public interface TargetLogicImpl implements TargetLogic {

    void consume() { 
        //Quelque chose de traitement
    }

}

Enfin, nous appellerons la logique.

Application.java


public class Application {
    private final TargetLogic targetLogic = ServiceFactory.getInstance().getTargetLogic();
}

Vous pouvez maintenant obtenir la logique via la fabrique dans la classe ʻApplication`.

Comment était-ce?

Comme je l'ai lu au début, l'application était petite et la structure du projet était simple, donc la méthode de gestion des dépendances était parfaite. Même s'il y a un changement de logique dans le futur, il semble qu'il puisse être organisé simplement parce qu'il suffit d'ajouter une méthode à l'usine. Quand devez-vous créer une instance? Ne devrait-il pas être fait? C'était un effet secondaire qui a approfondi ma réflexion.

D'un autre côté, si votre projet est un peu plus grand ou comporte plus de couches, il est plus simple de s'appuyer sur des bibliothèques comme Spring et Guice. Pour être honnête, il peut y avoir plus de projets qui sont difficiles à exécuter.

référence

Recommended Posts

Gestion des dépendances dans une architecture en couches
Notes sur l'utilisation du plug-in de gestion des dépendances
Gestion des dépendances dans Gradle à l'aide du référentiel Maven sur Amazon S3