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 ne possède qu’une seule instance dans toute 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 connexions ou les services de journalisation.
Le modèle fonctionne en rendant le constructeur privé, ce qui empêche 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() renvoie le même objet. L’instance est créée uniquement lorsqu’elle est demandée pour la première fois. C’est ce qu’on appelle l’initialisation différée :
DatabaseConnection db1 = DatabaseConnection.getInstance();
DatabaseConnection db2 = DatabaseConnection.getInstance();
System.out.println(db1 == db2); // true - same 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 renvoie l’instance. Cette combinaison garantit que, quel que soit le nombre de fois où vous demandez l’objet, vous obtenez toujours le même.
Défi
FacileConstruisons un gestionnaire de configuration pour une application en utilisant le modèle Singleton ! 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 où elles y demandent l'accès.
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 comporter :Un champ statique privé pour contenir l'unique instance.
Un champ privé de type String appelé
appNameet un champ privé de type int 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 différée), puis la renvoie.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 maximal 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 pour le nombre maximal d'utilisateurs (entier).Commencez par obtenir une instance de
AppConfiget stockez-la dans une variable appeléeconfig1. AppelezdisplaySettings()pour afficher les valeurs par défaut.Mettez ensuite à jour les paramètres à l'aide de 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 suivant : le nouveau nom d'application (String), puis la nouvelle valeur pour le nombre maximal d'utilisateurs (entier).
Ce défi démontre l'avantage fondamental du modèle Singleton : quel que soit le nombre de fois où vous demandez la configuration, vous obtenez toujours la même instance avec le même état partagé !
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]" using 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érateurEntraînez-vous par vous-même : Compilateur Java en ligne