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
