Fabrikmuster
Teil des Abschnitts Objektorientierte Programmierung der Ruby-Journey von Coddy. Lektion 43 von 57.
Das Fabrikmuster bündelt die Objekterstellung an einer Stelle. Aufrufer fragen nach dem, was sie benötigen, oft anhand eines Namens, und erhalten ein fertiges Objekt, ohne zu wissen, 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 leichter erweiterbar. Klassen sind Objekte, daher können sie in einem Hash gespeichert und 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 Fabrik kann anderem Code auch erlauben, zur Laufzeit neue Arten zu registrieren, sodass das Hinzufügen einer Art nicht bedeutet, die Fabrik zu bearbeiten:
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, und niemals von den konkreten Klassen. Eine neue Form bedeutet eine neue Klasse und einen neuen Eintrag in der Factory, ohne dass irgendwo anders Änderungen erforderlich sind:
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) verwenden 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 Art in einer eingefrorenen Hash-Konstanten KINDS und gibt bei einer unbekannten Art nil zurück.
Der bereitgestellte Code liest Zeilen 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 Eingabe-/Ausgabecode und kann nicht bearbeitet werden.
Probier es selbst
require_relative 'shape'
require_relative 'square'
require_relative 'circle'
require_relative 'triangle'
require_relative 'shape_factory'
# Mitgelieferter Ein-/Ausgabe-Code: belasse ihn wie er ist
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