Menu
CoddyTech

Method pabrik

Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan Ruby di Coddy. Pelajaran 15 dari 57.

factory method adalah method class yang membuat dan mengembalikan sebuah instance. Factory method memberi nama pada salah satu cara untuk membuat object. Di dalam method class, new berarti 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

Output:

100.0
0

Mengubah teks menjadi object adalah tugas umum bagi factory. Parsing berada di dekat class, dan initialize tetap sederhana:

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

Output:

90
7205

Sebuah factory dapat menolak input yang tidak valid. Mengembalikan nil memungkinkan pemanggil menguji hasilnya dengan if; memunculkan error akan menghentikan program kecuali pemanggil menanganinya dengan rescue:

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

Output:

ok #ff8800
not a color: orange

private_class_method :new membuat new hanya bisa dipanggil dari dalam class, sehingga factory menjadi satu-satunya cara untuk membuat object:

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

Output:

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

Tantangan

Mudah

Lengkapi class Duration. initialize(seconds) menyimpan jumlah detik. Factory Duration.parse(text) membaca m:ss atau h:mm:ss, factory Duration.from_minutes(m) menerima jumlah menit bulat, plus(other) mengembalikan Duration baru dengan jumlahnya, dan to_s mengembalikan h:mm:ss dengan menit dan detik yang terdiri dari dua digit.

Kode yang disediakan membaca durasi: baris seperti 45m diproses melalui from_minutes, sedangkan baris lainnya melalui parse. Kode tersebut mencetak setiap durasi, lalu mencetak total 1:47:10.

Tulis kodemu di duration.rb. main.rb berisi kode input/output yang disediakan dan tidak boleh diedit.

Coba sendiri

require_relative 'duration'

# Kode input/output yang disediakan: biarkan apa adanya
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 iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Objek

Latihan sendiri: Compiler Ruby online