Pour traiter du design pattern Factory en Ruby (dans le framework Rails), j’ai repris les exemples faits en PHP il y a déjà 7 ans !
Comme les principes ne diffèrent pas d’un langage à l’autre, seul le code figurera ici. Pour les explications, je vous renvoie au lien ci-dessus !
# on importe de quoi utiliser constantize
require 'active_support/inflector'
# l'interface des fabriques (ici une classe abstraite)
class FabriqueFacture
def initialize
raise "Impossible d'instancier la classe abstraite FabriqueFacture"
end
def fabriquer
raise NotImplementedError
end
end
# les fabriques concrètes
class FabriqueEnteteFacture < FabriqueFacture
CLASSE_CIBLE = 'Entete'
private_constant :CLASSE_CIBLE
def initialize
# on écrase le constructeur qui lève une exception dans la classe mère
end
def fabriquer
CLASSE_CIBLE.constantize.new
end
end
class FabriqueCorpsFacture < FabriqueFacture
CLASSE_CIBLE = 'Corps'
private_constant :CLASSE_CIBLE
def initialize(produits)
@produits = produits
end
def fabriquer
CLASSE_CIBLE.constantize.new(@produits)
end
private
attr_accessor :produits
end
class FabriquePiedPageFacture < FabriqueFacture
CLASSE_CIBLE = 'PiedPage'
private_constant :CLASSE_CIBLE
def initialize
# même remarque que pour le constructeur de FabriqueEnteteFacture
end
def fabriquer
CLASSE_CIBLE.constantize.new
end
end
# les produits CONCRETS
class PiedPage
def formater
"Je formate mon pied de page"
end
end
class Entete
def formater()
"Je formate mon entête"
end
end
class Corps
def initialize (produits)
@produits = produits
end
def formater
"Je formate mon corps avec mes #{@produits.count} produits"
end
end
# le code client pour tester toute la chaîne
class Facturation
def initialize(fabrique_entete, fabrique_corps, fabrique_pied)
if !((fabrique_entete.is_a? FabriqueFacture) &&
(fabrique_corps.is_a? FabriqueFacture) &&
(fabrique_pied.is_a? FabriqueFacture))
raise "Les fabriques doivent dériver FabriqueFacture"
end
@entete = fabrique_entete.fabriquer
@corps = fabrique_corps.fabriquer
@pied = fabrique_pied.fabriquer
end
def declencher
puts @entete.formater
puts @corps.formater
puts @pied.formater
end
private
attr_accessor :entete, :corps, :pied
end
produits = ['Gourde', 'Ballon', 'Pioche']
facturation = Facturation.new(
FabriqueEnteteFacture.new,
FabriqueCorpsFacture.new(produits),
FabriquePiedPageFacture.new
)
facturation.declencher

