2.1. Création des objets▲
Tout d'abord, nous allons nous intéresser aux patterns permettant la création d'objets. En effet, la difficulté réside dans le fait d'assembler des objets de base (dit "atomiques") pour obtenir des objets complexes. Pour cela, on dispose le plus souvent d'objets spécialisés dans l'assemblage et la construction.
2.1.1. Factory Method▲
Le pattern Factory Method permet de dissocier la classe de l'instanciation des objets de cette classe. Cette façon de faire peut se révéler plus souple que l'utilisation de construteurs "classiques", notamment dans le cas d'objets complexes (Composites en particulier).
On se retrouve donc avec 2 hiérarchies: d'une part, la hiérarchie des classes porteuses de données et d'autre part, la hiérarchie des "fabriques" (Factory) permettant d'en instancier les objets.
Le pattern Factory Method définit une interface pour la création d'objets (ou groupes d'objets). Ce sont les sous-classes qui implémentent la manière dont ces objets sont instanciés.
2.1.2. Prototype▲
Le pattern Prototype consiste à créer de nouveaux objets à partir d'objets existants, par simple recopie. Cela permet ainsi d'élaborer de nouveaux prototypes qui pourront être réutilisés plus tard.
Le principe du pattern Prototype est très simple: une méthode clone() permet de faire une copie conforme d'un objet. Il est alors possible de modifier cette copie afin de créer un objet différent. Cette copie peut ensuite être sauvegardée afin d'être utilisée plus tard ou copiée à son tour.
Afin de gérer les différents Prototypes, on peut utiliser un gestionnaire de Prototypes qui permet de stocker les prototypes, les classer, les enregistrer, les retrouver en se basant sur leurs identifiants, etc. (cette étape n'est cependant pas obligatoire).
Dans un éditeur de niveaux pour un jeu vidéo, on peut imaginer que l'on dispose de formes de bases (implémentées dans le moteur de jeu). Avec ces formes on créé des objets plus complexes que l'on pourra mettre en mémoire, dupliquer (grâce au pattern Prototype), modifier et sauvegarder dans des fichiers afin de les réutiliser plus tard. D'où l'intérêt du pattern Prototype et d'un gestionnaire de prototypes.
Le pattern Prototype se marie très bien avec le pattern Composite, par exemple.
2.1.3. Builder▲
Les Builders fournissent une interface simple permettant la construction d'objets complexes avant de retourner l'objet complètement construit à la fin. De cette manière, il est possible de définir une interface commmune pour des processus de construction différents.
Un objet de type Builder comporte au moins :
- des méthodes pour créer chaque élément de l'objet en construction
- une méthode pour retourner l'objet une fois terminé
Dans le livre de Gamma et al., les auteurs prennent comme exemple un constructeur de labyrinthe. Le labyrinthe est construit pièce par pièce au moyen de méthodes comme makeRoom et makeDoor. En se basant sur la même interface, ils créent ensuite un Builder qui ne construit pas l'objet réel mais ne fait que compter le nombre de pièces et de portes qui auraient été créés.
Outre le fait de pouvoir définir des processus de construction différents avec une interface commune (et avoir ainsi des Builder interchangeables), l'intérêt d'un Builder est de pouvoir étendre les processus de construction, par exemple en vérifiant que l'objet en cours de construction répond bien à certaines contraintes (et pouvoir, au besoin, lever une exception).
Un objet de type Builder ne s'utilise jamais seul. Les Builders ne font que définir une interface (pour la classe abstraite) et implémenter la manière dont les différents éléments sont construits (pour les classes concrètes). Les méthodes créant les différents éléments de l'objet ont besoin d'être appelées de l'extérieur (par un parseur, une interface homme-machine, un tout autre objet).