Strateji Deseni
Coddy'nin Ruby Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 45 / 57.
strateji deseni, bir algoritmanın bir bölümünü kendi nesnesine yerleştirir ve ana nesnenin bu bölümü devretmesini sağlar. Stratejiyi değiştirmek, ana sınıfı değiştirmeden davranışı değiştirir:
class Standard
def cost(kg)
5 + kg * 1.5
end
end
class Express
def cost(kg)
15 + kg * 3
end
end
class Shipment
attr_writer :strategy
def initialize(kg, strategy)
@kg = kg
@strategy = strategy
end
def cost
@strategy.cost(@kg)
end
end
s = Shipment.new(2, Standard.new)
puts s.cost
s.strategy = Express.new
puts s.costÇıktı:
8.0
21Stratejiler yalnızca bir yöntem adını paylaşır; bu nedenle cost özelliğine sahip herhangi bir nesne çalışır: yine ördek tiplemesi. Yeni bir gönderim yöntemi eklemek, Shipment içinde başka bir dal eklemek yerine tek bir sınıf eklemek anlamına gelir:
class Pickup
def cost(_kg)
0
end
end
shipment.strategy = Pickup.new # Shipment değişmediRuby'de bir strateji genellikle bir lambda'dır. call'a yanıt veren her şey, lambda, bir yöntem nesnesi veya kendi sınıfınızdan bir nesne olması fark etmeksizin saklanabilir ve çağrılabilir:
class TextFormatter
def initialize(strategy)
@strategy = strategy
end
def format_all(words)
words.map { |w| @strategy.call(w) }.join(" ")
end
end
class Censor
def call(word)
word.size > 3 ? "*" * word.size : word
end
end
words = %w[ruby is great]
puts TextFormatter.new(->(w) { w.upcase }).format_all(words)
puts TextFormatter.new(:capitalize.to_proc).format_all(words)
puts TextFormatter.new(Censor.new).format_all(words)Çıktı:
RUBY IS GREAT
Ruby Is Great
**** is *****Program çalışırken bir nesnenin davranışını değiştirmesi gerektiğinde veya değişiklik tek bir adımdan oluştuğunda, alt sınıflar yerine stratejiyi tercih edin. Bir alt sınıf, davranışı nesnenin tüm yaşamı boyunca sabitler:
# alt sınıflama: oluşturma anında sabit
ExpressShipment.new(2)
# strateji: daha sonra değiştirilebilir
shipment = Shipment.new(2, Standard.new)
shipment.strategy = Express.newGörev
KolayGönderim stratejilerini ve ShippingCalculator sınıfını tamamla. Standard#cost(kg), 5 artı kg başına 1.50; Express#cost(kg), 15 artı kg başına 3 ve Pickup#cost(kg), 0 değerindedir. Hesaplayıcı bir stratejiyle oluşturulur, strategy= ile strateji değiştirilebilir ve quote(kg), stratejinin sınıf adını kullanarak 2.5 kg by Express: 22.50 değerini döndürür.
Sağlanan kod Standard ile başlar ve use express, use pickup, use standard veya quote 2.5 komutlarını okur; her fiyat teklifini yazdırır.
Kodun standard.rb, express.rb, pickup.rb ve shipping_calculator.rb dosyalarına yazılmalıdır. main.rb, sağlanan girdi/çıktı kodunu içerir ve düzenlenemez.
Kendin dene
require_relative 'standard'
require_relative 'express'
require_relative 'pickup'
require_relative 'shipping_calculator'
# Sağlanan girdi/çıktı kodu: olduğu gibi bırakın
input = []
while (line = gets)
input << line.chomp
end
strategies = { "standard" => Standard, "express" => Express, "pickup" => Pickup }
calc = ShippingCalculator.new(Standard.new)
input.each do |line|
cmd, arg = line.split
if cmd == "use"
calc.strategy = strategies[arg].new
else
puts calc.quote(arg.to_f)
end
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