Menu
Coddy logo textTech

Durum Deseni

Coddy'nin Ruby Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 49 / 57.

durum deseni, bir nesnenin mevcut durumuna bağlı olan davranışı ayrı durum nesnelerine taşır. Ana nesne olan bağlam, bir durumu tutar ve çağrıları ona iletir; bir durum yanıt verir ve sıradaki durumun hangisi olacağına karar verir:

class Red
  def next_state
    Green.new
  end

  def to_s
    "red"
  end
end

class Green
  def next_state
    Yellow.new
  end

  def to_s
    "green"
  end
end

class Yellow
  def next_state
    Red.new
  end

  def to_s
    "yellow"
  end
end

class TrafficLight
  def initialize
    @state = Red.new
  end

  def change
    @state = @state.next_state
    self
  end

  def to_s
    "light is #{@state}"
  end
end

light = TrafficLight.new
puts light
puts light.change
puts light.change.change

Çıktı:

light is red
light is green
light is red

Desen olmadan, bağlamın her yöntemi bir durum değeri üzerinde case ifadesine ihtiyaç duyar ve yeni bir durum, bunların hepsini düzenlemek anlamına gelir. Durum nesneleriyle her durum, kendi kurallarını barındıran bir sınıftır:

# desen olmadan
def can_go?
  case @status
  when :red then false
  when :green then true
  when :yellow then false
  end
end

# desen ile
def can_go?
  @state.can_go?
end

Durumlar, kendilerine uymayan bir olayı reddedebilir. Burada bir taslak doğrudan yayımlanamaz; önce incelemeden geçmesi gerekir:

class Draft
  def submit
    Review.new
  end

  def publish
    raise ArgumentError, "cannot publish a draft"
  end

  def to_s
    "draft"
  end
end

class Review
  def publish
    Published.new
  end

  def to_s
    "in review"
  end
end

class Published
  def to_s
    "published"
  end
end

state = Draft.new
begin
  state.publish
rescue ArgumentError => e
  puts e.message
end
state = state.submit
state = state.publish
puts state

Çıktı:

cannot publish a draft
published

Paylaşılan bir temel sınıf, her duruma her olayı reddetmek gibi varsayılan yanıtı sağlayabilir; böylece her durum yalnızca kabul ettiği olayları tanımlar:

class State
  def submit
    raise ArgumentError, "cannot submit #{self}"
  end

  def approve
    raise ArgumentError, "cannot approve #{self}"
  end
end

class Review < State
  def approve
    Published.new
  end
end
challenge icon

Görev

Kolay

Trafik ışığını tamamla. Red, Green ve Yellow durumlarının her birinde next_state (kırmızı yeşile, yeşil sarıya, sarı kırmızıya geçer), can_go? (yalnızca yeşilde) ve to_s (renk) bulunur. TrafficLight kırmızıdan başlar, change bir sonraki duruma geçer ve status duruma sorarak red: stop veya green: go döndürür.

Sağlanan kod change veya status komutlarını okur ve her komuttan sonra durumu yazdırır.

Kodun red.rb, green.rb, yellow.rb ve traffic_light.rb dosyalarına yazılmalıdır. main.rb sağlanan girdi/çıktı kodunu içerir ve düzenlenemez.

Kendin dene

require_relative 'red'
require_relative 'green'
require_relative 'yellow'
require_relative 'traffic_light'

# Sağlanan girdi/çıktı kodu: olduğu gibi bırakın
input = []
while (line = gets)
  input << line.chomp
end
light = TrafficLight.new
input.each do |cmd|
  light.change if cmd == "change"
  puts light.status
end
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler

Kendi başına pratik yap: Online Ruby derleyicisi