Pattern Factory
Fa parte della sezione Programmazione orientata agli oggetti del percorso Ruby di Coddy. Lezione 43 di 57.
Il pattern factory concentra la creazione degli oggetti in un unico posto. Chi chiama richiede ciò di cui ha bisogno, spesso indicandolo per nome, e riceve un oggetto già pronto senza sapere quale classe è stata istanziata:
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).inspectOutput:
9
nilUna mappa dai nomi alle classi rende la factory più breve e facile da estendere. Le classi sono oggetti, quindi possono essere memorizzate in una mappa e inviare loro 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
endOutput:
Meow
unknown animal: cowUna factory può anche consentire ad altro codice di registrare nuovi tipi in fase di esecuzione, così aggiungere un tipo non significa modificare la factory:
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.namesOutput:
zipping
["zip"]I chiamanti dipendono solo da ciò che gli oggetti possono fare, qui area o speak, mai dalle classi concrete. Una nuova forma significa una nuova classe e una nuova voce nella factory, senza modifiche in nessun altro punto:
shape = ShapeFactory.create(kind, size) # Square, Circle, ...
puts shape.area # il chiamante non indica mai una classeSfida
FacileCompleta le forme e ShapeFactory.create(kind, size). Square, Circle e Triangle (equilatero) condividono la classe base Shape, il cui to_s restituisce square 3: area 9.00, con il nome della classe in minuscolo, la dimensione e l’area con due cifre decimali. Usa 3.14159 per pi greco e Math.sqrt(3) / 4 * size**2 per il triangolo. La factory cerca il tipo in una costante hash congelata KINDS e restituisce nil per un tipo sconosciuto.
Il codice fornito legge righe come square 3, chiede alla factory di creare ogni forma e la stampa, oppure stampa unknown shape: hexagon.
Il tuo codice va inserito in shape.rb, square.rb, circle.rb, triangle.rb e shape_factory.rb. main.rb contiene il codice di input/output fornito e non può essere modificato.
Provalo tu
require_relative 'shape'
require_relative 'square'
require_relative 'circle'
require_relative 'triangle'
require_relative 'shape_factory'
# Supplied input/output code: keep it as it is
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
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Classi e oggetti
Lavorare con i fileDefinire le classiVariabili d'istanzaMetodi e selfto_s e inspectRipasso - Tessera della biblioteca4Incapsulamento
Metodi privatiMetodi protettiSetter privatiProteggere lo statoRiepilogo - Distributore automatico7Polimorfismo e Duck Typing
PolimorfismoDuck TypingMetodi astratticase e classiRiepilogo - Metodi di pagamento10Pattern di progettazione Parte 2
Delegazione con ForwardablePattern DecoratorPattern BuilderPattern State2Metodi di accesso e self
Metodi di lettura e scritturaSetter personalizzatiself nei metodiIdentità e uguaglianzaRiepilogo - Elenco contatti5Ereditarietà
SottoclassiRidefinizione dei metodiChiamare superis_a? e antenatiRiepilogo - Paghe del personale8Metodi speciali
Uguaglianza e hashMetodi degli operatoriIndicizzazione e appendCollezioni personalizzateRiepilogo - Frazioni11Progetto: Gestione della biblioteca
Libri e iscrittiPrendere in prestito i libriEsercitati da solo: Compilatore Ruby online