Menu
Coddy logo textTech

Méthodes de fabrique

Fait partie de la section Programmation orientée objet du Journey Ruby de Coddy. Leçon 15 sur 57.

Une méthode fabrique est une méthode de classe qui crée et renvoie une instance. Elle donne un nom à une façon de construire un objet. Dans une méthode de classe, new signifie 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

Sortie :

100.0
0

Transformer du texte en objet est une tâche courante pour une fabrique. L’analyse se trouve à côté de la classe, et initialize reste simple :

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

Sortie :

90
7205

Une fabrique peut refuser une entrée incorrecte. Renvoyer nil permet à l’appelant de tester le résultat avec if ; lever une erreur arrête le programme, à moins que l’appelant ne la capture :

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

Sortie :

ok #ff8800
not a color: orange

private_class_method :new rend new appelable uniquement à l'intérieur de la classe, de sorte que les fabriques deviennent le seul moyen de créer un objet :

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

Sortie :

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

Défi

Facile

Complétez la classe Duration. initialize(seconds) stocke un nombre de secondes. La méthode de fabrique Duration.parse(text) lit m:ss ou h:mm:ss, la méthode de fabrique Duration.from_minutes(m) prend un nombre entier de minutes, plus(other) renvoie un nouvel objet Duration contenant la somme, et to_s renvoie h:mm:ss avec des minutes et des secondes sur deux chiffres.

Le code fourni lit les durées : les lignes comme 45m passent par from_minutes, les autres par parse. Il affiche chaque durée, puis finalement total 1:47:10.

Votre code doit se trouver dans duration.rb. main.rb contient le code fourni pour les entrées et les sorties et ne peut pas être modifié.

Essayez vous-même

require_relative 'duration'

# Code d'entrée/sortie fourni : le garder tel quel
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 iconTestez-vous

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

Entraînez-vous par vous-même : Compilateur Ruby en ligne