Métodos de Fábrica
Parte da seção Programação orientada a objetos do Journey de Ruby da Coddy. Lição 15 de 57.
Um método de fábrica é um método de classe que cria e retorna uma instância. Ele dá um nome a uma maneira de construir um objeto. Dentro de um método de classe, 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.celsiusSaída:
100.0
0Transformar texto em um objeto é uma tarefa comum para uma fábrica. A análise fica próxima da classe, e initialize permanece simples:
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").secondsSaída:
90
7205Uma fábrica pode recusar uma entrada inválida. Retornar nil permite que o chamador teste o resultado com if; gerar um erro interrompe o programa, a menos que o chamador o trate:
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}"
endSaída:
ok #ff8800
not a color: orangeprivate_class_method :new faz com que new possa ser chamado apenas dentro da classe, então as fábricas se tornam a única maneira de criar um 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
endSaída:
250
private method `new' called for class MoneyDesafio
FácilComplete a classe Duration. initialize(seconds) armazena um número de segundos. A fábrica Duration.parse(text) lê m:ss ou h:mm:ss, a fábrica Duration.from_minutes(m) recebe minutos inteiros, plus(other) retorna uma nova Duration com a soma, e to_s retorna h:mm:ss com minutos e segundos de dois dígitos.
O código fornecido lê durações: linhas como 45m passam por from_minutes, e as demais passam por parse. Ele imprime cada duração e, por fim, total 1:47:10.
Seu código deve ficar em duration.rb. main.rb contém o código fornecido de entrada/saída e não pode ser editado.
Experimente você mesmo
require_relative 'duration'
# Código de entrada/saída fornecido: mantenha-o 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 lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação orientada a objetos
1Classes e Objetos
Trabalhando com ArquivosDefinindo ClassesVariáveis de InstânciaMétodos e selfto_s e inspectRevisão - Cartão da Biblioteca4Encapsulamento
Métodos privadosMétodos protegidosSetters privadosProtegendo o estadoRevisão - Máquina de venda automática7Polimorfismo e Duck Typing
PolimorfismoDuck TypingMétodos Abstratoscase e ClassesRevisão - Métodos de Pagamento2Acessores e self
Leitores e GravadoresSetters Personalizadosself nos MétodosIdentidade e IgualdadeRecapitulação - Lista de Contatos5Herança
SubclassesSobrescrita de métodosChamando superis_a? e ancestraisRevisão - Folha de pagamento da equipe8Métodos Especiais
Igualdade e hashMétodos de OperadoresIndexação e AdiçãoColeções PersonalizadasRevisão - Frações11Projeto: Gerenciamento de Biblioteca
Livros e MembrosEmpréstimo de Livros3Métodos e Variáveis de Classe
Métodos de ClasseVariáveis de Instância da ClasseConstantesMétodos de FábricaRevisão - Códigos de CupomPratique por conta própria: Compilador de Ruby online