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