Dekoratör Deseni
Coddy'nin Ruby Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 47 / 57.
Dekoratör deseni, bir nesneyi aynı arayüze sahip başka bir nesnenin içine sarar ve çağrıyı iletmeden önce veya sonra bir şey ekler. Dekoratörler herhangi bir sırayla üst üste eklenebilir:
class Coffee
def cost
2.0
end
def description
"coffee"
end
end
class Milk
def initialize(drink)
@drink = drink
end
def cost
@drink.cost + 0.5
end
def description
"#{@drink.description}, milk"
end
end
order = Milk.new(Milk.new(Coffee.new))
puts format("%s: %.2f", order.description, order.cost)Çıktı:
coffee, milk, milk: 3.00Her dekoratör, sarmalanan nesneyi saklar ve çağrıları ona iletir; bu nedenle ortak bir temel sınıf bu kısmı üstlenebilir. Ardından her somut dekoratör yalnızca değiştirdiği kısımları geçersiz kılar:
class Coffee
def cost
2.0
end
def description
"coffee"
end
end
class Extra
def initialize(drink)
@drink = drink
end
def cost
@drink.cost
end
def description
@drink.description
end
end
class Sugar < Extra
def cost
super + 0.2
end
def description
super + ", sugar"
end
end
order = Sugar.new(Coffee.new)
puts format("%s: %.2f", order.description, order.cost)Çıktı:
coffee, sugar: 2.20Standart kütüphanenin SimpleDelegator sınıfı (require 'delegate'), tanımlamadığı her yöntemi sarmalanmış nesneye yönlendirir; bu da arayüz büyük olduğunda dekoratörleri kısa tutar:
require 'delegate'
class Loud < SimpleDelegator
def to_s
super.upcase + "!"
end
end
text = Loud.new("hello")
puts text
puts text.size
puts text.start_with?("he")Çıktı:
HELLO!
5
trueDecorator'lar çalışma zamanında tekil nesnelere davranış ekler ve serbestçe birleştirilebilir. Alt sınıflarla, MilkSugarCoffee gibi her bileşimin kendine ait bir sınıfa ihtiyacı olurdu:
Sugar.new(Milk.new(Coffee.new)) # herhangi bir kombinasyon, herhangi bir sıra
Whip.new(Sugar.new(Coffee.new))
# alt sınıflarla: MilkCoffee, SugarCoffee, MilkSugarCoffee, ...Görev
KolayKahve dekoratörlerini tamamla. Coffee 2.00 tutarındadır ve coffee olarak açıklanır. Milk 0.50 ve , milk, Sugar 0.20 ve , sugar, Whip ise 0.70 ve , whip ekler. Üç dekoratör, sarılmış içeceği depolayan ve cost ile description'ı ileten temel sınıf Extra'yı paylaşır; her alt sınıf super kullanır.
Her girdi satırı milk sugar gibi bir sipariştir. Sağlanan kod, yeni bir Coffee'yi dekoratörlerle bu sırayla sarar ve coffee, milk, sugar: 2.70 çıktısını yazdırır.
Kodun coffee.rb, extra.rb, milk.rb, sugar.rb ve whip.rb dosyalarına yazılmalıdır. main.rb sağlanan girdi/çıktı kodunu içerir ve düzenlenemez.
Kendin dene
require_relative 'coffee'
require_relative 'extra'
require_relative 'milk'
require_relative 'sugar'
require_relative 'whip'
# Sağlanan girdi/çıktı kodu: olduğu gibi bırakın
input = []
while (line = gets)
input << line.chomp
end
extras = { "milk" => Milk, "sugar" => Sugar, "whip" => Whip }
input.each do |line|
drink = line.split.reduce(Coffee.new) { |d, name| extras[name].new(d) }
puts format("%s: %.2f", drink.description, drink.cost)
end
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
1Sınıflar ve Nesneler
Dosyalarla ÇalışmaSınıf TanımlamaÖrnek DeğişkenleriMetotlar ve selfto_s ve inspectÖzet - Kütüphane Kartı7Çok Biçimlilik ve Ördek Tiplemesi
Çok BiçimlilikÖrdek TiplemesiSoyut Metotlarcase ve SınıflarTekrar - Ödeme Yöntemleri2Erişimciler ve self
Okuyucular ve YazıcılarÖzel Setter'larMetotlarda selfKimlik ve EşitlikTekrar - Kişi Listesi5Kalıtım
Alt sınıflarMetotları geçersiz kılmasuper çağrısıis_a? ve üst sınıflarTekrar - Personel Maaşları8Özel Metotlar
Eşitlik ve hashOperatör Metotlarıİndeksleme ve EklemeÖzel KoleksiyonlarTekrar - Kesirler11Proje: Kütüphane Yönetimi
Kitaplar ve ÜyelerKitap Ödünç Alma3Sınıf Metotları ve Değişkenleri
Sınıf MetotlarıSınıf Örnek DeğişkenleriSabitlerFabrika MetotlarıTekrar - Kupon KodlarıKendi başına pratik yap: Online Ruby derleyicisi