Patron Factory
Fait partie de la section Programmation orientée objet du Journey Ruby de Coddy. Leçon 43 sur 57.
Le modèle de fabrique regroupe la création des objets en un seul endroit. Les appelants demandent ce dont ils ont besoin, souvent par nom, et reçoivent un objet prêt à l’emploi sans savoir quelle classe a été construite :
class Square
def initialize(side)
@side = side
end
def area
@side * @side
end
end
class Circle
def initialize(r)
@r = r
end
def area
(3.14159 * @r * @r).round(2)
end
end
class ShapeFactory
def self.create(kind, size)
case kind
when "square" then Square.new(size)
when "circle" then Circle.new(size)
end
end
end
puts ShapeFactory.create("square", 3).area
puts ShapeFactory.create("hexagon", 3).inspectRésultat :
9
nilUn hash associant des noms à des classes rend la fabrique plus courte et plus facile à étendre. Les classes sont des objets, elles peuvent donc être stockées dans un hash et recevoir new :
class Dog
def speak
"Woof"
end
end
class Cat
def speak
"Meow"
end
end
class AnimalFactory
KINDS = { "dog" => Dog, "cat" => Cat }.freeze
def self.create(kind)
klass = KINDS.fetch(kind) { raise ArgumentError, "unknown animal: #{kind}" }
klass.new
end
end
puts AnimalFactory.create("cat").speak
begin
AnimalFactory.create("cow")
rescue ArgumentError => e
puts e.message
endSortie :
Meow
unknown animal: cowUne fabrique peut également permettre à d’autres morceaux de code d’enregistrer de nouveaux types à l’exécution, de sorte que l’ajout d’un type ne nécessite pas de modifier la fabrique :
class Plugins
@kinds = {}
class << self
def register(name, klass)
@kinds[name] = klass
end
def build(name)
@kinds.fetch(name).new
end
def names
@kinds.keys.sort
end
end
end
class Zip
def run
"zipping"
end
end
Plugins.register("zip", Zip)
puts Plugins.build("zip").run
p Plugins.namesRésultat :
zipping
["zip"]Les appelants dépendent uniquement de ce que les objets peuvent faire, ici area ou speak, jamais des classes concrètes. Une nouvelle forme signifie une nouvelle classe et une nouvelle entrée dans la fabrique, sans aucune modification ailleurs :
shape = ShapeFactory.create(kind, size) # Square, Circle, ...
puts shape.area # l'appelant ne nomme jamais une classeDéfi
FacileComplète les formes et ShapeFactory.create(kind, size). Square, Circle et Triangle (équilatéral) partagent la classe de base Shape, dont to_s renvoie square 3: area 9.00, avec le nom de la classe en minuscules, la taille et l’aire avec deux décimales. Utilise 3.14159 pour pi et Math.sqrt(3) / 4 * size**2 pour le triangle. La fabrique recherche le type dans une constante de hachage gelée KINDS et renvoie nil pour un type inconnu.
Le code fourni lit les lignes square 3, demande à la fabrique de créer chaque forme et l’affiche, ou affiche unknown shape: hexagon.
Ton code doit se trouver dans shape.rb, square.rb, circle.rb, triangle.rb et shape_factory.rb. main.rb contient le code fourni d’entrée/sortie et ne peut pas être modifié.
Essayez vous-même
require_relative 'shape'
require_relative 'square'
require_relative 'circle'
require_relative 'triangle'
require_relative 'shape_factory'
# Code d'entrée/sortie fourni : le garder tel quel
input = []
while (line = gets)
input << line.chomp
end
input.each do |line|
kind, size = line.split
shape = ShapeFactory.create(kind, size.to_f)
puts shape || "unknown shape: #{kind}"
end
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation orientée objet
1Classes et objets
Travailler avec des fichiersDéfinir des classesVariables d’instanceMéthodes et selfto_s et inspectRécapitulatif - Carte de bibliothèque4Encapsulation
Méthodes privéesMéthodes protégéesSetters privésProtéger l’étatRécapitulatif - Distributeur automatique7Polymorphisme et typage canard
PolymorphismeTypage canardMéthodes abstraitesCas et classesRécapitulatif - méthodes de paiement10Patrons de conception – Partie 2
Délégation avec ForwardablePatron DécorateurPatron BuilderPatron État2Accesseurs et self
Lecteurs et écrivainsSetters personnalisésself dans les méthodesIdentité et égalitéRécapitulatif - Liste de contacts5Héritage
Sous-classesRedéfinition des méthodesAppeler superis_a? et ancêtresRécapitulatif - Paie du personnel8Méthodes spéciales
Égalité et hachageMéthodes d’opérateursIndexation et ajoutCollections personnaliséesRécapitulatif - Fractions11Projet : Gestion de bibliothèque
Livres et membresEmprunter des livresEntraînez-vous par vous-même : Compilateur Ruby en ligne