Veuillez monter !
Le design pattern Builder, appelé « Monteur » en français est un design pattern de création dont le but est d’aider à créer des objets complexes. Pour cela, il intègre une classe appelée directeur qui contrôle l’algorithme de construction.
Composants du design pattern Builder
Les composants participant à ce pattern sont les suivants:
- Le directeur, qui prend en composition un monteur
- Une abstraction pour les monteurs
- Des monteurs concrets
- Des parties
- Des produits (la cible finale !)
Dans l’exemple qui suit, nous aurons:
- Des monteurs de camions et de voitures
- Des produits : Camion et Voiture
- Des parties : porte, moteur, roue
- Un directeur qui orchestre la construction de tout ça
Nos abstractions seront des classes abstraites simulées (pas d’interface en Ruby, ni de classes abstraites stricto sensu).
class Piece def donnerNom raise "Impossible d'instancier la classe ProduitEntretien" end end class PorteCamion < Piece def donnerNom "Porte de camion" end end class PorteVoiture < Piece def donnerNom "Porte de voiture" end end class RoueCamion < Piece def donnerNom "Roue de camion" end end class RoueVoiture < Piece def donnerNom "Roue de voiture" end end class MoteurVoiture < Piece def donnerNom "Moteur de voiture" end end class MoteurCamion < Piece def donnerNom "Moteur de camion" end end class Vehicule def initialize @configuration = {} end def ajouter_piece(nom, piece) @configuration[nom] = piece end protected attr_reader :configuration end class Camion < Vehicule end class Voiture < Vehicule end class Directeur def initialize (monteur) @monteur = monteur end def monter @monteur.creer_vehicule @monteur.poser_portes @monteur.poser_moteur @monteur.poser_roues @monteur.peindre end private attr_reader :monteur end class Monteur def initialize raise "Impossible d'instancier la classe abstraite Monteur" end def creer_vehicule raise NotImplementedError end def poser_portes raise NotImplementedError end def poser_moteur raise NotImplementedError end def poser_roues raise NotImplementedError end def peindre raise NotImplementedError end def donner_vehicule raise NotImplementedError end end class MonteurVoitures < Monteur def initialize(options) @options = options end def creer_vehicule @voiture = Voiture.new end def poser_portes @voiture.ajouter_piece('porte AVG', PorteVoiture.new) @voiture.ajouter_piece('porte AVD', PorteVoiture.new) @voiture.ajouter_piece('porte arrière', PorteVoiture.new) if 3 < @options['nb_portes'] @voiture.ajouter_piece('porte ARG', PorteVoiture.new) @voiture.ajouter_piece('porte ARD', PorteVoiture.new) end end def poser_moteur @voiture.ajouter_piece('moteur', MoteurVoiture.new) end def poser_roues @voiture.ajouter_piece('roue AVG', RoueVoiture.new) @voiture.ajouter_piece('roue AVD', RoueVoiture.new) @voiture.ajouter_piece('roue ARG', RoueVoiture.new) @voiture.ajouter_piece('roue ARD', RoueVoiture.new) end def peindre puts "Je peins la voiture en " + @options['couleur_peinture'] end def donner_vehicule @voiture end private attr_reader :voiture, :options end class MonteurCamions < Monteur def initialize(options) @options = options end def creer_vehicule @camion = Camion.new end def poser_portes @camion.ajouter_piece('porte AVG', PorteCamion.new) @camion.ajouter_piece('porte AVD', PorteCamion.new) end def poser_moteur @camion.ajouter_piece('moteur', MoteurCamion.new) end def poser_roues @camion.ajouter_piece('roue AVG', RoueCamion.new) @camion.ajouter_piece('roue AVD', RoueCamion.new) @camion.ajouter_piece('roue ARG', RoueCamion.new) @camion.ajouter_piece('roue ARD', RoueCamion.new) end def peindre puts "Je peins le camion en " + @options['couleur_peinture'] end def donner_vehicule @camion end private attr_reader :camion, :options end monteur_voitures = MonteurVoitures.new({'nb_portes' => 5, 'couleur_peinture' => 'rouge'}) monteur_camions = MonteurCamions.new({'couleur_peinture' => 'bleu'}) [monteur_voitures, monteur_camions].each do |monteur| directeur = Directeur.new(monteur) directeur.monter vehicule = monteur.donner_vehicule end