Patron Singleton
Fait partie de la section Programmation Orientée Objet du Journey Java de Coddy — leçon 65 sur 87.
Le Singleton Pattern est un patron de conception de création qui garantit qu'une classe n'a qu'une seule instance tout au long de votre application, tout en fournissant un point d'accès global à cette instance. Cela est utile pour les ressources qui doivent être partagées, comme les gestionnaires de configuration, les pools de connexion ou les services de journalisation.
Le patron fonctionne en rendant le constructeur privé, empêchant ainsi l'instanciation directe. À la place, une méthode statique contrôle l'accès à l'instance unique :
public class DatabaseConnection {
private static DatabaseConnection instance;
// Le constructeur privé empêche l'instanciation directe
private DatabaseConnection() {
System.out.println("Connection created");
}
// Point d'accès global
public static DatabaseConnection getInstance() {
if (instance == null) {
instance = new DatabaseConnection();
}
return instance;
}
public void query(String sql) {
System.out.println("Executing: " + sql);
}
}Chaque appel à getInstance() retourne le même objet. L'instance est créée uniquement lors de la première demande — c'est ce qu'on appelle l'initialisation paresseuse :
DatabaseConnection db1 = DatabaseConnection.getInstance();
DatabaseConnection db2 = DatabaseConnection.getInstance();
System.out.println(db1 == db2); // true - même instanceLes composants clés d'un Singleton sont : un champ private static contenant l'instance, un constructeur private, et une méthode public static qui retourne l'instance. Cette combinaison garantit que peu importe le nombre de fois que vous demandez l'objet, vous obtenez toujours le même.
Défi
FacileConstruisons un gestionnaire de configuration pour une application en utilisant le Singleton Pattern ! Votre gestionnaire de configuration garantira que toutes les parties de votre application partagent les mêmes paramètres, quel que soit le nombre de fois qu'elles demandent à y accéder.
Vous organiserez votre code sur deux fichiers :
AppConfig.java: Créez une classe Singleton qui gère les paramètres de configuration de l'application. VotreAppConfigdoit avoir :Un champ statique privé pour contenir l'instance unique.
Un champ String privé appelé
appNameet un champ int privé appelémaxUsers.Un constructeur privé qui initialise
appNameà"MyApplication"etmaxUsersà100, puis afficheAppConfig initialized.Une méthode statique publique
getInstance()qui crée l'instance uniquement si elle n'existe pas encore (initialisation paresseuse), puis la retourne.Une méthode
setAppName(String name)qui met à jour le nom de l'application.Une méthode
setMaxUsers(int max)qui met à jour le nombre maximum d'utilisateurs.Une méthode
displaySettings()qui afficheApp: [appName], Max Users: [maxUsers].Main.java: Démontrez que votre Singleton fonctionne correctement ! Vous recevrez deux entrées : un nouveau nom d'application (String) et une nouvelle valeur de nombre maximum d'utilisateurs (entier).Tout d'abord, obtenez une instance de
AppConfiget stockez-la dans une variable appeléeconfig1. AppelezdisplaySettings()pour afficher les valeurs par défaut.Ensuite, mettez à jour les paramètres en utilisant vos valeurs d'entrée en appelant
setAppNameetsetMaxUserssurconfig1.Obtenez une autre instance et stockez-la dans
config2. AppelezdisplaySettings()surconfig2pour prouver qu'elle reflète les modifications effectuées viaconfig1.Enfin, affichez si les deux références pointent vers le même objet :
Same instance: [true/false]en comparantconfig1 == config2.
Vous recevrez deux entrées dans l'ordre : le nouveau nom de l'application (String) et le nouveau nombre maximum d'utilisateurs (entier).
Ce défi démontre l'avantage principal du Singleton Pattern : peu importe le nombre de fois que vous demandez la configuration, vous obtenez toujours la même instance avec le même état partagé !
Aide-mémoire
Le Singleton Pattern (Patron de conception Singleton) garantit qu'une classe n'a qu'une seule instance dans toute l'application, fournissant un point d'accès global à cette instance.
Composants clés :
- Un champ
private staticcontenant l'unique instance - Un constructeur
privatepour empêcher l'instanciation directe - Une méthode
public staticqui retourne l'instance
Implémentation de base :
public class DatabaseConnection {
private static DatabaseConnection instance;
// Le constructeur privé empêche l'instanciation directe
private DatabaseConnection() {
System.out.println("Connection created");
}
// Point d'accès global
public static DatabaseConnection getInstance() {
if (instance == null) {
instance = new DatabaseConnection();
}
return instance;
}
public void query(String sql) {
System.out.println("Executing: " + sql);
}
}Utilisation :
DatabaseConnection db1 = DatabaseConnection.getInstance();
DatabaseConnection db2 = DatabaseConnection.getInstance();
System.out.println(db1 == db2); // true - même instanceL'instance n'est créée que lors de la première demande — c'est ce qu'on appelle l'initialisation paresseuse (lazy initialization). Chaque appel à getInstance() retourne le même objet, garantissant un état partagé dans toute l'application.
Essayez vous-même
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Lire les entrées
String newAppName = scanner.nextLine();
int newMaxUsers = scanner.nextInt();
// TODO: Obtenir la première instance de AppConfig et la stocker dans config1
// TODO: Appeler displaySettings() sur config1 pour afficher les valeurs par défaut
// TODO: Mettre à jour les paramètres en utilisant setAppName et setMaxUsers sur config1
// TODO: Obtenir une autre instance et la stocker dans config2
// TODO: Appeler displaySettings() sur config2 pour prouver que les modifications sont partagées
// TODO: Afficher si les deux références pointent vers le même objet :
// "Same instance: [true/false]" en utilisant config1 == config2
}
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation Orientée Objet
1Fondamentaux de la POO
Fichiers externesIntroduction à la POOClasses vs ObjetsLe mot-clé thisMéthodesChamps (Attributs)Méthode constructeurSurcharge de constructeurRécapitulatif - Calculatrice simple4Héritage
Héritage de base (extends)Le mot-clé superRedéfinition de méthode (@Override)Chaînage de constructeursLa classe ObjectHéritage simple et multiniveauPourquoi pas d'héritage multiple de classesRécapitulatif - Hiérarchie des employés7Méthodes spéciales et classe Object
Méthode toString()equals() et hashCode()Méthode clone()compareTo() et ComparableInterface ComparatorRécapitulatif - Tri personnalisé2Modificateurs d'accès et Encapsulation
Aperçu des niveaux d'accèsMéthodes Getter et SetterMasquage d'informationsLe mot-clé finalRécapitulatif - Gestionnaire de compte bancaire5Polymorphisme
Bases de la surcharge de méthodesRedéfinition de méthodes (Run-Time)Upcasting et DowncastingL'opérateur instanceofClasses et méthodes abstraitesRécapitulatif - Calculateur de formes8Concepts avancés de la POO
Composition vs HéritageAgrégation vs CompositionClasses internes, imbriquées et anonymesEnums et méthodes d'EnumRecords (Java 16+)Classes scellées (Java 17+)11Patrons de conception, partie 1
Introduction aux patrons de conceptionPatron SingletonPatron FabriquePatron MonteurPatron ObservateurPatron Stratégie3Propriétés de classe et membres statiques
Variables d'instance vs variables statiquesMéthodes statiquesBlocs statiquesConstantes (static final)Récapitulatif - Compteur et utilitaire6Interfaces et Classes Abstraites
Introduction aux InterfacesImplémentation d'InterfacesImplémentation d'Interfaces MultiplesDefault et Static dans les InterfacesClasses Abstraites vs InterfacesInterfaces FonctionnellesRécapitulatif - Système de Paiement9La généricité
Introduction à la généricitéClasses génériquesMéthodes génériquesParamètres de type bornésWildcards (?, extends, super)Récapitulatif - Conteneur générique12Patrons de conception, partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Template MethodPatron ÉtatPatron CompositePatron Itérateur