Métodos de fábrica
Parte de la sección Programación orientada a objetos del Journey de Ruby de Coddy. Lección 15 de 57.
Un método de fábrica es un método de clase que crea y devuelve una instancia. Da un nombre a una forma de construir un objeto. Dentro de un método de clase, new significa 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.celsiusSalida:
100.0
0Convertir texto en un objeto es una tarea común para una fábrica. El análisis se encuentra junto a la clase, y initialize se mantiene 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").secondsSalida:
90
7205Una fábrica puede rechazar entradas no válidas. Devolver nil permite que quien llama compruebe el resultado con if; generar un error detiene el programa a menos que quien llama lo 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}"
endSalida:
ok #ff8800
not a color: orangeprivate_class_method :new hace que new solo se pueda invocar dentro de la clase, por lo que las fábricas se convierten en la única forma de crear un objeto:
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
endSalida:
250
private method `new' called for class MoneyDesafío
FácilCompleta la clase Duration. initialize(seconds) almacena una cantidad de segundos. La fábrica Duration.parse(text) lee m:ss o h:mm:ss, la fábrica Duration.from_minutes(m) recibe minutos enteros, plus(other) devuelve una nueva instancia de Duration con la suma, y to_s devuelve h:mm:ss con minutos y segundos de dos dígitos.
El código proporcionado lee duraciones: las líneas como 45m pasan por from_minutes y el resto por parse. Imprime cada duración y finalmente total 1:47:10.
Tu código va en duration.rb. main.rb contiene el código proporcionado de entrada/salida y no se puede editar.
Pruébalo tú mismo
require_relative 'duration'
# Código de entrada/salida suministrado: déjalo tal como está
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) }}"
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación orientada a objetos
1Clases y objetos
Trabajar con archivosDefinir clasesVariables de instanciaMétodos y selfto_s e inspectRepaso: tarjeta de biblioteca4Encapsulación
Métodos privadosMétodos protegidosAsignadores privadosProtección del estadoRepaso: máquina expendedora7Polimorfismo y tipado pato
PolimorfismoTipado patoMétodos abstractoscase y clasesRepaso: métodos de pago2Accesores y self
Lectores y escritoresSetters personalizadosself en los métodosIdentidad e igualdadRepaso: lista de contactos5Herencia
SubclasesSobrescritura de métodosLlamar a superis_a? y ancestrosRepaso - Nómina del personal8Métodos especiales
Igualdad y hashMétodos de operadoresIndexación y adiciónColecciones personalizadasRepaso: fracciones11Proyecto: Gestión de biblioteca
Libros y miembrosPréstamo de libros3Métodos y variables de clase
Métodos de claseVariables de instancia de claseConstantesMétodos de fábricaRepaso: códigos de cupónPractica por tu cuenta: Compilador de Ruby online