Iterator Kalıbı
Coddy'nin Lua Journey'sinin Object Oriented Programming bölümünün bir parçası — ders 64 / 70.
Bir nesne içinde saklanan bir öğe koleksiyonuna sahip olduğunuzda, genellikle bunlar üzerinde döngü kurmak istersiniz. Lua'nın genel for döngüsü, özel yineleyicilerle harika çalışır ve bu işlevselliği doğrudan sınıflarınızın içine oluşturabilirsiniz.
Iterator deseni, bir nesnenin dahili verilerinin nasıl dolaşılacağını kontrol etmesini sağlar. Zarif bir yaklaşım, bir nesneyi bir fonksiyon gibi çağrılabilir hale getiren __call metametodunu kullanmaktır. Her çağrı, başka öğe kalmayana kadar bir sonraki öğeyi döndürür.
local Collection = {}
Collection.__index = Collection
function Collection:new()
local obj = { items = {}, index = 0 }
setmetatable(obj, Collection)
return obj
end
function Collection:add(item)
table.insert(self.items, item)
end
function Collection:__call()
self.index = self.index + 1
return self.items[self.index]
end
__call tanımlandığında, bir while döngüsü kullanarak yineleme yapabilir veya nesneyi doğrudan genel bir for döngüsüne geçirebilirsiniz:
local bag = Collection:new()
bag:add("apple")
bag:add("banana")
for item in bag do
print(item)
end
Döngü, bag() fonksiyonunu tekrar tekrar çağırır. __call, nil döndürdüğünde (başka öğe kalmadığında), döngü durur. Bu desen, yineleme mantığını nesnenin kendi içinde kapsüller ve öğelere nasıl ve hangi sırayla erişileceği konusunda size tam kontrol sağlar.
Görev
KolayLua'nın genel for döngüsünü kullanarak üzerinde gezinebileceğiniz bir Playlist sınıfı oluşturalım! Playlist'inizin şarkı şarkı taranmasını sağlamak için __call metametodunu kullanarak Iterator desenini uygulayacaksınız.
Kodunuzu iki dosya halinde düzenleyeceksiniz:
Playlist.lua: Şarkıları dahili olarak saklayan bir Playlist sınıfı oluşturun. Sınıfınızın, boş bir şarkı listesi başlatan ve yineleme dizinini (index) 0'a ayarlayan bir:new()yapıcı metoduna (constructor) ihtiyacı vardır. Çalma listesine şarkı eklemek için bir:addSong(title)metodu ekleyin. En önemlisi, çalma listesi her "çağrıldığında" listedeki bir sonraki şarkıyı (veya daha fazla şarkı kalmadığındanil) döndürmesi için__callmetametodunu uygulayın.main.lua: Playlist modülünüzü dahil edin (require) ve yeni bir çalma listesi oluşturun. Aldığınız girdilere göre listeye şarkılar ekleyin, ardından çalma listesi üzerinde gezinmek ve her şarkı başlığını kendi satırına yazdırmak için genel birfordöngüsü kullanın.
Iterator deseninin sihri, Playlist nesnenizin çağrılabilir hale gelmesidir; bir for döngüsünde kullanıldığında, Lua onu nil döndürene kadar tekrar tekrar çağırır ve size her şarkıyı sırayla verir.
Çalma listenize (sırasıyla) eklenecek bir şarkı başlığını temsil eden üç girdi alacaksınız.
Örneğin, girdiler Bohemian Rhapsody, Stairway to Heaven ve Hotel California ise, çıktı şöyle olmalıdır:
Bohemian Rhapsody
Stairway to Heaven
Hotel CaliforniaGirdiler Yesterday, Imagine ve Let It Be ise, çıktı şöyle olmalıdır:
Yesterday
Imagine
Let It BeKopya kağıdı
Iterator deseni, bir nesnenin özel yineleme mantığı uygulayarak dahili verilerinin nasıl gezileceğini kontrol etmesine olanak tanır.
Bir nesneyi bir fonksiyon gibi çağrılabilir hale getirmek için __call metametodunu kullanın. Her çağrı, daha fazla öğe kalmayana kadar bir sonraki öğeyi döndürür (nil döndürür):
local Collection = {}
Collection.__index = Collection
function Collection:new()
local obj = { items = {}, index = 0 }
setmetatable(obj, Collection)
return obj
end
function Collection:add(item)
table.insert(self.items, item)
end
function Collection:__call()
self.index = self.index + 1
return self.items[self.index]
end
__call tanımlandığında, nesneyi doğrudan genel bir for döngüsünde kullanabilirsiniz:
local bag = Collection:new()
bag:add("apple")
bag:add("banana")
for item in bag do
print(item)
end
Döngü nesneyi tekrar tekrar çağırır. __call nil döndürdüğünde, döngü otomatik olarak durur.
Kendin dene
-- Playlist modülünü dahil et
local Playlist = require('Playlist')
-- Girdiden üç şarkı başlığı oku
local song1 = io.read()
local song2 = io.read()
local song3 = io.read()
-- TODO: Playlist:new() kullanarak yeni bir çalma listesi oluştur
-- TODO: :addSong() kullanarak üç şarkıyı çalma listesine ekle
-- TODO: Çalma listesi üzerinde gezinmek için genel bir for döngüsü kullan
-- ve her şarkı başlığını kendi satırına yazdır
-- İpucu: for song in playlist do ... end
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Object Oriented Programming bölümündeki tüm dersler
1'Self' Kavramı
Fonksiyonlu TablolarAçık 'self'İki Nokta SözdizimiNokta vs İki NoktaÖzet - Hareket Eden Nokta4Proje: Dijital Banka
Proje KurulumuPara Yatırma Metodu7Çok Biçimlilik ve Geçersiz Kılma
Metotları Geçersiz KılmaÜst Sınıf Metotlarını ÇağırmaDuck TypingOrtak ArayüzTür KontrolüÖzet - Çalışan Rolleri2Sınıf Prototip Kalıbı
Prototip Kavramı__index ile Bağlama:new() KurucusuÖznitelikleri BaşlatmaBağımsız ÖrneklerÖzet - Araba Fabrikası5OOP'de Operatör Aşırı Yükleme
Nesneleri ToplamaNesneleri ÇıkarmaNesneleri BirleştirmeNesneleri Karşılaştırma (<, >)Özet - Cüzdan Matematiği8Kapsülleme
Adlandırma KurallarıGizlilik için Closure'larClosure'lar Aracılığıyla ErişimSalt Okunur TablolarDoğrulama MantığıÖzet - Güvenli Kasa11Tasarım Kalıpları (Lite)
Fabrika FonksiyonlarıSingleton TablosuIterator KalıbıObserver (Dinleyici)Özet - Logger Fabrikası3Nesne Durumu ve Davranışı
Örnek DeğişkenleriGetter MetotlarıSetter MetotlarıHesaplanmış ÖzelliklerString BiçimlendirmeEşitlik KontrolleriÖzet - Öğrenci Notu6Kalıtımın Temelleri
Kalıtım KurulumuMetot KalıtımıConstructor'ı GenişletmeAlt Sınıf Metotları EklemePaylaşılan ve BenzersizÖzet - Şekil Hiyerarşisi