Menu
CoddyTech

Factory-Methoden

Teil des Abschnitts Objektorientierte Programmierung der Ruby-Journey von Coddy. Lektion 15 von 57.

Eine Fabrikmethode ist eine Klassenmethode, die eine Instanz erstellt und zurückgibt. Sie gibt einer Möglichkeit, ein Objekt zu erstellen, einen Namen. Innerhalb einer Klassenmethode bedeutet new self.new:

class Temperature
  attr_reader :celsius

  def initialize(celsius)
    @celsius = celsius
  end

  def self.from_fahrenheit(f)
    new((f - 32) * 5 / 9.0)
  end

  def self.freezing
    new(0)
  end
end

puts Temperature.from_fahrenheit(212).celsius
puts Temperature.freezing.celsius

Ausgabe:

100.0
0

Text in ein Objekt umzuwandeln, ist eine typische Aufgabe für eine Factory. Das Parsen befindet sich neben der Klasse, und initialize bleibt einfach:

class Duration
  attr_reader :seconds

  def initialize(seconds)
    @seconds = seconds
  end

  def self.parse(text)
    new(text.split(":").map(&:to_i).reduce(0) { |acc, part| acc * 60 + part })
  end
end

puts Duration.parse("1:30").seconds
puts Duration.parse("2:00:05").seconds

Ausgabe:

90
7205

Eine Factory kann ungültige Eingaben ablehnen. Die Rückgabe von nil ermöglicht es dem Aufrufer, das Ergebnis mit if zu prüfen; das Auslösen eines Fehlers stoppt das Programm, sofern der Aufrufer ihn nicht abfängt:

class Color
  attr_reader :hex

  def initialize(hex)
    @hex = hex
  end

  def self.parse(text)
    return nil unless text.match?(/\A#[0-9a-f]{6}\z/i)

    new(text.downcase)
  end
end

["#FF8800", "orange"].each do |text|
  color = Color.parse(text)
  puts color ? "ok #{color.hex}" : "not a color: #{text}"
end

Ausgabe:

ok #ff8800
not a color: orange

private_class_method :new macht new nur innerhalb der Klasse aufrufbar, sodass die Factory-Methoden die einzige Möglichkeit sind, ein Objekt zu erstellen:

class Money
  attr_reader :cents

  def initialize(cents)
    @cents = cents
  end
  private_class_method :new

  def self.from_cents(cents)
    new(cents)
  end
end

puts Money.from_cents(250).cents
begin
  Money.new(250)
rescue NoMethodError => e
  puts e.message
end

Ausgabe:

250
private method `new' called for class Money
challenge icon

Aufgabe

Einfach

Vervollständige die Klasse Duration. initialize(seconds) speichert eine Anzahl von Sekunden. Die Factory Duration.parse(text) liest m:ss oder h:mm:ss, die Factory Duration.from_minutes(m) nimmt ganze Minuten entgegen, plus(other) gibt eine neue Duration mit der Summe zurück, und to_s gibt h:mm:ss mit zweistelligen Minuten- und Sekundenangaben zurück.

Der bereitgestellte Code liest Zeitdauern ein: Zeilen wie 45m werden über from_minutes verarbeitet, die übrigen über parse. Er gibt jede Zeitdauer aus und schließlich total 1:47:10.

Dein Code gehört in duration.rb. main.rb enthält den bereitgestellten Ein-/Ausgabecode und kann nicht bearbeitet werden.

Probier es selbst

require_relative 'duration'

# Vorgegebener Ein-/Ausgabecode: unverändert lassen
input = []
while (line = gets)
  input << line.chomp
end
durations = input.map do |line|
  line.end_with?("m") ? Duration.from_minutes(line.to_i) : Duration.parse(line)
end
durations.each { |d| puts d }
puts "total #{durations.reduce(Duration.new(0)) { |sum, d| sum.plus(d) }}"
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-Ruby-Compiler