CodeGym /Blog Java /Random-FR /Modèles et Singleton en Java
Auteur
Jesse Haniel
Lead Software Architect at Tribunal de Justiça da Paraíba

Modèles et Singleton en Java

Publié dans le groupe Random-FR
Cet article s'adresse à toute personne qui, pour la première fois, rencontre le concept de modèles de conception, a entendu le terme singleton ou a mis en œuvre d'une manière ou d'une autre le modèle singleton mais n'a pas compris ce qui se passait. Accueillir! Les élèves de CodeGym rencontrent des modèles de conception pour la première fois au niveau 15, lorsque le capitaine leur demande de manière inattendue de "renforcer" leur compréhension en implémentant le modèle Java Singleton avec une implémentation paresseuse. Les étudiants qui entendent parler du modèle singleton pour la première fois se posent instantanément de nombreuses questions : qu'est-ce qu'un modèle de conception ? Pourquoi en avons-nous besoin? Qu'est-ce qu'un singleton ? Et enfin, qu'est-ce que la mise en œuvre paresseuse ? Répondons à ces questions dans l'ordre.

Qu'est-ce qu'un design pattern ?

Je crois qu'un peu d'histoire est nécessaire pour répondre à cette question avec la meilleure compréhension. Il y a quatre auteurs de programmation célèbres (Erich Gamma, John Vlissides, Ralph Johnson et Richard Helm) qui ont eu une idée intéressante. Ils ont remarqué que le développement de logiciels les obligeait souvent à résoudre à peu près les mêmes problèmes et à écrire du code structuré de la même manière. Ils ont donc décidé de décrire des modèles typiques qui doivent souvent être utilisés dans la programmation orientée objet. Leur livre a été publié en 1994 sous le titre Design Patterns: Elements of Reusable Object-Oriented Software. Le nom du livre s'est avéré trop long et les gens ont commencé à l'appeler simplement le livre du Gang des Quatre. La première édition comprenait 23 patrons. Par la suite, des dizaines d'autres modèles ont été découverts.
Un modèle de conception est une solution standardisée à un problème commun.
Et le modèle singleton n'est que l'un d'entre eux.

Pourquoi avons-nous besoin de patrons de conception ?

Vous pouvez programmer sans connaître les schémas : après tout, au niveau 15, vous avez déjà écrit des centaines de mini-programmes sur CodeGym sans même savoir qu'ils existent. Cela suggère que les modèles de conception sont une sorte d'outil dont l'utilisation distingue le maître de l'amateur : les modèles de conception décrivent comment résoudre correctement un problème typique. Cela signifie que connaître les modèles vous fait gagner du temps. En ce sens, ils s'apparentent à des algorithmes. Par exemple, vous pouvez créer votre propre algorithme de tri avec un blackjack et des nombreset passez beaucoup de temps à le faire, ou vous pourriez en mettre en œuvre un qui a été compris et décrit depuis longtemps. Il en va de même pour les modèles de conception. De plus, avec les modèles de conception, le code devient plus standard, et lorsque vous utilisez le modèle approprié, vous êtes moins susceptible de faire des erreurs, car les pièges courants du modèle ont été identifiés et éliminés il y a longtemps. En plus de tout le reste, la connaissance des modèles aide les programmeurs à mieux se comprendre. Vous pouvez simplement dire le nom d'un motif au lieu d'essayer de fournir une longue explication à vos collègues programmeurs. En résumé, les modèles de conception vous aident à :
  • ne pas réinventer la roue, mais plutôt utiliser des solutions standard ;
  • standardiser le code ;
  • normaliser la terminologie;
Pour conclure cette section, notons que l'ensemble du corps des patrons de conception peut être divisé en trois grands groupes : Patterns et singleton - pour tous ceux qui les rencontrent pour la première fois - 2

Enfin, le modèle singleton

Singleton est un pattern créationnel . Ce modèle garantit qu'il n'y a qu'une seule instance d'une classe et fournit un point d'accès global pour cet objet. D'après la description, il doit être clair que ce modèle doit être appliqué dans deux cas :
  1. lorsque votre programme exige que pas plus d'un objet d'une classe particulière ne soit créé. Par exemple, un jeu vidéo peut avoir une classe Héros et un seul objet Héros décrivant le seul héros du jeu.

  2. lorsque vous devez fournir un point d'accès global à un objet. En d'autres termes, vous devez rendre l'objet disponible de n'importe où dans le programme. Hélas, il ne suffit pas de créer simplement une variable globale, car elle n'est pas protégée en écriture : n'importe qui peut modifier la valeur de la variable, de sorte que le point d'accès global de l'objet peut être perdu. Ces propriétés d'un Singleton sont nécessaires, par exemple, lorsque vous avez un objet qui fonctionne avec une base de données et que vous devez accéder à la base de données à partir de différentes parties du programme. Un singleton garantira que personne n'écrit de code qui remplace l'instance précédemment créée.
Ainsi, un Singleton satisfait ces deux besoins : il ne doit y avoir qu'un seul objet d'un certain type dans le programme et il doit y avoir un accès global à celui-ci. Dans l'exemple du niveau 15, le capitaine vous demande d'implémenter ce modèle pour la tâche suivante :
  1. Trouvez un exemple de Singleton avec initialisation différée.

  2. Créez trois classes singleton - Soleil, Lune, Terre - dans des fichiers séparés en utilisant le même principe.

  3. Mettre en œuvrePlanèteinterface dans les classes Soleil , Lune et Terre .

  4. Dans le bloc statique de la classe Solution , appelez lereadKeyFromConsoleAndInitPlanetméthode.

  5. Mettre en œuvre lereadKeyFromConsoleAndInitPlanetfonctionnalité de la méthode :

    • 5.1. Lire un paramètre String à partir de la console

    • 5.2. Si le paramètre est égal à l'un desPlanèteconstantes de l'interface, créez l'objet thePlanet approprié .

Après avoir lu attentivement les conditions de la tâche, nous pouvons clairement voir pourquoi un Singleton est nécessaire ici. En effet, on nous demande de créer une instance de chacune des classes suivantes : Sun , Moon , Earth . Il est logique de supposer que nous ne devrions pas créer plus d'un Soleil/Lune/Terre. Sinon, on se retrouve dans une situation absurde, à moins bien sûr que vous écriviez votre version de Star Wars. Implémentation du modèle Singleton en Java en trois étapes En Java, le comportement Singleton ne peut pas être implémenté à l'aide d'un constructeur ordinaire, car un constructeur renvoie toujours un nouvel objet. Par conséquent, toutes les implémentations de Singletonse résument à masquer le constructeur, à créer une méthode statique publique qui contrôle la durée de vie de l'objet singleton et à "détruire" tous les objets nouvellement apparus. Si un Singleton est accédé, il doit soit créer un nouvel objet (s'il n'en existe pas déjà dans le programme), soit en renvoyer un existant. Pour y parvenir:
  1. Vous devez donner à la classe un champ statique privé qui stocke un seul objet :

    
    public class LazyInitializedSingleton {
    	private static LazyInitializedSingleton instance; // #1
    }
    
  2. Rendez le constructeur (par défaut) privé. Cela signifie qu'il n'est pas accessible en dehors de la classe et ne pourra pas renvoyer de nouveaux objets :

    
    public class LazyInitializedSingleton {
    	private static LazyInitializedSingleton instance;
    private LazyInitializedSingleton(){} // #2
    } 
    
  3. Déclarez une méthode de création statique qui sera utilisée pour obtenir le singleton :

    
    public class LazyInitializedSingleton {
        private static LazyInitializedSingleton instance;
            private LazyInitializedSingleton() {}
            public static LazyInitializedSingleton getInstance() { // #3
            if (instance == null) { // If the object has not yet been created
                instance = new LazyInitializedSingleton(); // Create a new object
            }
            return instance; // Return the previously created object
        }
    }
    
L'exemple ci-dessus est quelque peu maladroit, car nous cachons simplement le constructeur et fournissons notre propre méthode au lieu d'un constructeur standard. Étant donné que cet article vise à garantir que les étudiants de CodeGym entrent en contact avec ce modèle (et les modèles de conception en général), les nuances des implémentations singleton plus complexes ne seront pas décrites ici. Nous notons seulement que, selon la complexité du programme, ce modèle peut devoir être affiné davantage. Par exemple, dans un environnement multithread (voir les articles sur les threads), plusieurs threads différents peuvent accéder simultanément à la méthode singleton, et le code décrit ci-dessus cessera de fonctionner, car chaque thread séparé pourrait créer une instance de la classe. Par conséquent, il existe encore plusieurs approches différentes pour créer des singletons thread-safe appropriés. Mais c'est une autre histoire =)

Et enfin... Quelle est cette initialisation paresseuse dont le capitaine a parlé ?

L'initialisation différée est également appelée initialisation différée. Il s'agit d'une astuce de programmation où une opération gourmande en ressources (et la création d'un objet est une opération gourmande en ressources) est effectuée à la demande plutôt qu'à l'avance. Alors, que se passe-t-il réellement dans notre code Java Singleton ? En d'autres termes, notre objet est créé au moment où il est accédé, pas à l'avance. Vous ne devriez pas supposer que l'initialisation paresseuse est d'une manière ou d'une autre rigidement liée au modèle Singleton . L'initialisation paresseuse est également utilisée dans d'autres modèles de conception de création, tels que Proxy et Factory Method, mais c'est aussi une autre histoire =)
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION