Fabrikmuster
Teil des Abschnitts Objektorientierte Programmierung der Ruby-Journey von Coddy. Lektion 43 von 57.
Das Factory-Muster bündelt die Objekterzeugung an einem Ort. Aufrufer fragen nach dem, was sie benötigen, oft anhand eines Namens, und erhalten ein fertiges Objekt, ohne wissen zu müssen, welche Klasse erstellt wurde:
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).inspectAusgabe:
9
nilEin Hash, der Namen Klassen zuordnet, macht die Factory kürzer und einfacher erweiterbar. Klassen sind Objekte, daher können sie in einem Hash gespeichert werden und ihnen kann new gesendet werden:
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
endAusgabe:
Meow
unknown animal: cowEine Factory kann auch anderem Code ermöglichen, zur Laufzeit neue Typen zu registrieren, sodass das Hinzufügen eines Typs keine Bearbeitung der Factory erfordert:
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.namesAusgabe:
zipping
["zip"]Die Aufrufer hängen nur davon ab, was die Objekte tun können, hier area oder speak, niemals von den konkreten Klassen. Eine neue Form bedeutet eine neue Klasse und einen neuen Eintrag in der Factory, und sonst keine Änderungen:
shape = ShapeFactory.create(kind, size) # Square, Circle, ...
puts shape.area # Der Aufrufer nennt nie eine KlasseAufgabe
EinfachVervollständige die Formen und ShapeFactory.create(kind, size). Square, Circle und Triangle (gleichseitig) teilen sich die Basisklasse Shape, deren to_s square 3: area 9.00 zurückgibt, mit dem Klassennamen in Kleinbuchstaben, der Größe und der Fläche mit zwei Dezimalstellen. Verwende 3.14159 für Pi und Math.sqrt(3) / 4 * size**2 für das Dreieck. Die Factory sucht die Form in der eingefrorenen Hash-Konstante KINDS und gibt für eine unbekannte Form nil zurück.
Der bereitgestellte Code liest Zeilen wie square 3, fragt die Factory für jede Form ab und gibt sie aus oder unknown shape: hexagon.
Dein Code gehört in shape.rb, square.rb, circle.rb, triangle.rb und shape_factory.rb. main.rb enthält den bereitgestellten Ein-/Ausgabecode und darf nicht bearbeitet werden.
Probier es selbst
require_relative 'shape'
require_relative 'square'
require_relative 'circle'
require_relative 'triangle'
require_relative 'shape_factory'
# Vorgegebener Ein-/Ausgabecode: unverändert lassen
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
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Klassen und Objekte
Arbeiten mit DateienKlassen definierenInstanzvariablenMethoden und selfto_s und inspectRückblick – Bibliotheksausweis4Kapselung
Private MethodenGeschützte MethodenPrivate SetterZustand schützenRückblick – Verkaufsautomat7Polymorphismus und Duck Typing
PolymorphismusDuck TypingAbstrakte MethodenFälle und KlassenRückblick – Zahlungsmethoden2Getter und Setter sowie self
Leser und SchreiberBenutzerdefinierte Setterself in MethodenIdentität und GleichheitWiederholung – Kontaktliste5Vererbung
UnterklassenMethoden überschreibensuper aufrufenis_a? und VorfahrenRückblick – Gehaltsabrechnung des Personals8Spezielle Methoden
Gleichheit und HashOperator-MethodenIndexieren und AnhängenBenutzerdefinierte CollectionsRückblick – Brüche11Projekt: Bibliotheksverwaltung
Bücher und MitgliederBücher ausleihenÜbe selbstständig: Online-Ruby-Compiler