3.1 Singleton
Singleton est un modèle de conception générique qui garantit qu'une application à thread unique aura une seule instance d'une classe et fournit un point d'accès global à cette instance.
Très souvent, les programmeurs novices aiment assembler des méthodes utilitaires dans une classe statique - une classe qui ne contient que des méthodes statiques. Cette approche présente un certain nombre d'inconvénients - par exemple, vous ne pouvez pas transmettre une référence à un objet d'une telle classe, de telles méthodes sont difficiles à tester, etc.
Comme alternative, une solution de classe singleton a été proposée : une classe qui ne peut avoir qu'un seul objet. Lors d'une tentative de création de cet objet, il n'est créé que s'il n'existe pas déjà, sinon une référence à une instance déjà existante est renvoyée.
Il est essentiel qu'il soit possible d'utiliser une instance de la classe, car dans de nombreux cas, des fonctionnalités plus larges deviennent disponibles. Par exemple, cette classe peut implémenter certaines interfaces et son objet peut être passé à d'autres méthodes en tant qu'implémentation de l'interface. Ce qui ne peut pas être fait avec un ensemble de méthodes statiques.
Avantages:
- Les méthodes sont liées à un objet, pas à une classe statique - vous pouvez passer un objet par référence.
- Les méthodes objet sont beaucoup plus faciles à tester et à simuler.
- Un objet n'est créé qu'en cas de besoin : initialisation d'un objet paresseux.
- Accélérer le lancement initial du programme s'il y a beaucoup de célibataires qui ne sont pas nécessaires pour le lancement.
- Seul peut être transformé en stratégie de modèle ou en plusieurs objets de ce type.
Moins :
- Il devient plus difficile de contrôler les courses et les retards entre les threads.
- Il est difficile d'écrire un "solitaire" multi-thread "de la tête": l'accès à un singleton de longue date, idéalement, ne devrait pas ouvrir un mutex. Des solutions mieux éprouvées.
- Un conflit entre deux threads sur un seul thread inachevé entraînera un retard.
- Si l'objet est créé pendant une longue période, le retard peut interférer avec l'utilisateur ou perturber le temps réel. Dans ce cas, il est préférable de transférer sa création à l'étape d'initialisation du programme.
- Des fonctionnalités spéciales sont requises pour les tests unitaires - par exemple, pour mettre la bibliothèque en mode "non solitaire" et isoler complètement les tests les uns des autres.
- Une tactique spéciale pour tester le programme fini est nécessaire, car même le concept de «la capacité de lancement la plus simple» disparaît, car la capacité de lancement dépend de la configuration.
3.2 Usine [Méthode]
Une méthode de fabrique est un modèle de conception générique qui fournit aux sous-classes (classes-héritiers) une interface pour créer des instances d'une certaine classe. Au moment de la création, les descendants peuvent déterminer quelle classe créer.
En d'autres termes, ce modèle délègue la création d'objets aux descendants de la classe parent. Cela vous permet d'utiliser non pas des classes concrètes dans le code du programme, mais de manipuler des objets abstraits à un niveau supérieur.
Ce modèle définit une interface pour créer un objet, mais laisse aux sous-classes le soin de décider sur quelle classe baser l'objet. Une méthode de fabrique permet à une classe de déléguer la création de sous-classes. Utilisé lorsque :
- la classe ne sait pas à l'avance quels objets de quelles sous-classes elle doit créer.
- une classe est conçue pour que les objets qu'elle crée soient spécifiés par des sous-classes.
- la classe délègue ses responsabilités à l'une des nombreuses sous-classes d'assistants, et il est prévu de déterminer quelle classe assume ces responsabilités.
3.3 Usine abstraite
Une usine abstraite est un modèle de conception générique qui fournit une interface pour créer des familles d'objets liés ou interdépendants sans spécifier leurs classes concrètes.
Le modèle est implémenté en créant une classe abstraite Factory, qui est une interface pour créer des composants système (par exemple, pour une interface de fenêtre, elle peut créer des fenêtres et des boutons). Ensuite, des classes sont écrites qui implémentent cette interface.
Il est utilisé dans les cas où le programme doit être indépendant du processus et des types de nouveaux objets créés. Lorsqu'il est nécessaire de créer des familles ou des groupes d'objets liés, excluant la possibilité d'utilisation simultanée d'objets de différents ensembles de ceux-ci dans le même contexte.
Forces:
- isole des classes spécifiques ;
- simplifie le remplacement des familles de produits ;
- garantit la compatibilité des produits.
Disons que votre programme fonctionne avec le système de fichiers. Ensuite, pour travailler sous Linux, vous avez besoin des objets LinuxFile, LinuxDirectory, LinuxFileSystem. Et pour travailler dans Windwos, vous avez besoin des classes WindowsFile, WindowsDirectory, WindowsFileSystem.
La classe Path, qui est créée via Path.of(), est un tel cas. Path n'est pas vraiment une classe, mais une interface, et il a des implémentations WindowsPath et LinuxPath. Et quel type d'objet sera créé est caché de votre code et sera décidé au moment de l'exécution.
3.4 Prototypage
Le prototype est un modèle de conception générative.
Ce modèle définit les types d'objets créés à l'aide d'une instance de prototype et crée de nouveaux objets en copiant ce prototype. Il permet de s'éloigner de l'implémentation et de suivre le principe de « programmation par interfaces ».
Une classe d'interface/abstraite au sommet de la hiérarchie est spécifiée comme type de retour, et les classes descendantes peuvent substituer un héritier qui implémente ce type là. En termes simples, il s'agit du modèle de création d'un objet en clonant un autre objet au lieu de le créer via un constructeur.
Le modèle est utilisé pour :
- éviter l'effort supplémentaire de créer un objet de manière standard (c'est-à-dire en utilisant un constructeur, puisque dans ce cas les constructeurs de toute la hiérarchie ancêtre de l'objet seront également appelés), lorsque cela est prohibitif pour l'application.
- évitez d'hériter du créateur d'objet dans l'application cliente, comme le fait le modèle de fabrique abstraite.
Utilisez ce modèle de conception lorsque votre programme ne se soucie pas de la façon dont il crée, compose et présente les produits :
- les classes instanciées sont déterminées au moment de l'exécution, par exemple à l'aide du chargement dynamique ;
- vous voulez éviter de créer des hiérarchies de classes ou d'usines parallèles aux hiérarchies de classes de produits ;
- Les instances de classe peuvent être dans l'un des différents états. Il peut être plus pratique de définir le nombre approprié de prototypes et de les cloner, plutôt que d'instancier manuellement la classe dans l'état approprié à chaque fois.
GO TO FULL VERSION