Quelques patrons de conception
Singleton et service locator
- La technique du singleton permet de manipuler une instance unique
- Elle peut être mise en place via une propriété ou méthode statique d'une classe qui retourne la même instance de cette classe
- Le constructeur d'une classe singleton est privé, pour interdire l'instanciation depuis du code externe
- Il est aussi possible de centraliser les singletons dans une seule classe qu'on appelle service locator
- Le service locator est préféré car il permet de centraliser la gestion des instances et peut apporter des fonctionnalités communes
Propriétés
class Mage {
private constructor(public name: string, public hp: number) {}
static readonly instance = new Mage("", 0);
}
Mage.instance.hp = 200;
console.log(Mage.instance.hp);
class Thief {
constructor(public name: string, public hp: number) {}
}
class ServiceLocator {
static get mage(): Mage {
return Mage.instance;
}
static readonly thief = new Thief("Picflouz", 100);
}
console.log(ServiceLocator.mage);
console.log(ServiceLocator.thief);
Fabrique (Factory) et Monteur (Builder)
- Une fabrique est une fonction qui génère des instances d'une classe via une fonction.
- Un monteur est similaire à la fabrique avec la différence que les paramètres sont initialisés sous forme d'une série d'appels.
- La technique du chaînage d'appels est souvent utilisée en complément.
- Ces techniques permettent de substituer l'implémentation sans avoir à changer le code qui demande une instance.
- Elle permettent aussi de proposer une syntaxe plus concise pour créer des objets complexes.
Fabrique et monteur
interface Transporter {
readonly capacity: number;
}
class SpaceShip implements Transporter {
constructor(
readonly speed: number,
readonly staelliteCount: number,
readonly capacity: number,
readonly shootPower: number
) {}
}
class Bus implements Transporter {
constructor(readonly capacity: number) {}
}
// Fabrique (ou Factory)
function createTransporter(capacity: number): Transporter {
return new Bus(capacity);
//return new SpaceShip(10, 1, 4, 2200);
}
const transporter = createTransporter(2);
console.log(transporter);
// Monteur (ou Builder)
class TransporterBuilder {
private capacity = 0;
constructor() {}
setCapacity(capacity: number) {
this.capacity = capacity;
// retourner this permet d'autoriser le chainage
return this;
}
build(): Transporter {
return new Bus(this.capacity);
}
}
const transporter2 = new TransporterBuilder().setCapacity(5).build();
console.log(transporter2);
Exercices
Exo 1
On souhaite modéliser un garage qui répare des véhicules.
Un véhicule est identifié par son matricule et a un état isBroken
de type booléen.
Il n'y qu'une instance de garage possible.
Le garage est identifié par son nom et permet de réparer un véhicule en basculant l'état isBroken
à false
.
Un véhicule réparé reste en garage tant que son propriétaire n'e l'a pas récupéré.
Si un véhicule n'est pas en panne, il est immédiatement remis à son propriétaire.
Un propriétaire est identifié par son nom et la listes des véhicules qu'il possède. Le propriétaire ne peut pas récupérer un véhicule qu'il ne possède pas.
Exo 2
Faire l'exercice 5.2 ce cette série avec les différences suivants:
- Utiliser TypeScript au lieu de Java
- Définir des factory (monteurs) pour instancier les différents enseignants (
createResearcherLecturer()
, etc.)