Singleton Tablosu
Coddy'nin Lua Journey'sinin Object Oriented Programming bölümünün bir parçası — ders 63 / 70.
Bazen tüm programınızda bir şeyin tam olarak bir örneğine ihtiyaç duyarsınız; bir yapılandırma yöneticisi, bir günlükleme sistemi veya oyun ayarları. Birden fazla kopya oluşturmak sorunlara yol açar: hangisi doğru veriye sahip? Singleton deseni yalnızca bir örneğin var olmasını sağlar.
Lua'da, modüllerin çalışma şekli sayesinde bir Singleton uygulamak şaşırtıcı derecede basittir. Bir modülü require ettiğinizde, Lua sonucu önbelleğe alır. require fonksiyonuna yapılan sonraki çağrılar, yeni bir tablo değil, önbelleğe alınmış tabloyu döndürür.
-- GameConfig.lua
local GameConfig = {
volume = 80,
difficulty = "normal"
}
function GameConfig:setVolume(v)
self.volume = v
end
return GameConfig
Şimdi, programınızın herhangi bir yerinde:
local config1 = require("GameConfig")
local config2 = require("GameConfig")
config1:setVolume(50)
print(config2.volume) -- 50 (aynı tablo!)
Hem config1 hem de config2 tam olarak aynı tabloya başvurur. Bir değişken üzerinden yapılan değişiklikler diğeri üzerinden görülebilir. Bu otomatik olarak gerçekleşir çünkü Lua'nın require fonksiyonu döndürülen değeri package.loaded içinde saklar ve onu tekrar kullanır.
Yeni nesneler oluşturan Factory pattern'in aksine, bir Singleton tüm uygulamanız genelinde paylaşılan bir durumu garanti eder. Bu, kodunuzun birden fazla bölümünün tutarlı bir şekilde erişmesi ve değiştirmesi gereken global ayarlar için idealdir.
Görev
KolaySingleton desenini kullanarak bir oyun ayarları yöneticisi oluşturalım! Programınızın her parçasının, kaç kez çağrılırsa çağrılsın, tam olarak aynı ayarlara erişmesini sağlayan bir yapılandırma modülü oluşturacaksınız.
Kodunuzu iki dosya halinde düzenleyeceksiniz:
GameSettings.lua: Oyun yapılandırmasını saklayan bir Singleton modülü oluşturun. Ayarlar tablonuzmusicVolume(70 ile başlar),sfxVolume(100 ile başlar) vedifficulty("normal"ile başlar) içermelidir. Bu ayarları değiştirmek için üç yöntem ekleyin::setMusicVolume(value),:setSfxVolume(value)ve:setDifficulty(level). Modülün sonunda tabloyu döndürmeyi unutmayın!main.lua: GameSettings modülünüzü iki farklı değişkene çağırarak (require) Singleton'ın çalıştığını kanıtlayın. Müzik sesini ve zorluğu değiştirmek için ilk değişkeni kullanın. Ardından, üç ayarın tümünü yazdırmak için ikinci değişkeni kullanın; eğer Singleton doğru çalışıyorsa, her iki değişken de aynı tabloya başvurur, bu nedenle biri aracılığıyla yapılan değişiklikler diğeri aracılığıyla görünür olur.
İki girdi alacaksınız:
- Yeni müzik sesi (bir sayı)
- Yeni zorluk seviyesi (
"easy"veya"hard"gibi bir dize)
Ayarları ilk değişken üzerinden değiştirdikten sonra, ikinci değişkeni kullanarak üç ayarı şu sırayla her biri kendi satırında olacak şekilde yazdırın: müzik sesi, sfx sesi ve ardından zorluk.
Örneğin, girdiler 50 ve hard ise, çıktı şöyle olmalıdır:
50
100
hardGirdiler 25 ve easy ise, çıktı şöyle olmalıdır:
25
100
easySfx sesinin hiç değiştirmediğimiz için varsayılan değeri olan 100'de kaldığına, ancak müzik sesinin ve zorluğun ilk değişken üzerinden yapılan değişiklikleri yansıttığına dikkat edin; bu, her iki değişkenin de aynı Singleton örneğine işaret ettiğini kanıtlar!
Kopya kağıdı
Singleton deseni, tüm programınız boyunca bir nesnenin yalnızca bir örneğinin bulunmasını sağlar. Bu, birden fazla örneğin veri tutarsızlığına neden olacağı yapılandırma yöneticileri, günlükleme sistemleri veya oyun ayarları için kullanışlıdır.
Lua'da Singleton deseni, modül sistemi aracılığıyla doğal bir şekilde uygulanır. Bir modülü require ettiğinizde, Lua sonucu package.loaded içinde önbelleğe alır. Sonraki require çağrıları, yeni bir tablo değil, aynı önbelleğe alınmış tabloyu döndürür.
Bir Singleton modülü oluşturma:
-- GameConfig.lua
local GameConfig = {
volume = 80,
difficulty = "normal"
}
function GameConfig:setVolume(v)
self.volume = v
end
return GameConfig
Singleton'ı kullanma:
local config1 = require("GameConfig")
local config2 = require("GameConfig")
config1:setVolume(50)
print(config2.volume) -- 50 (aynı tablo!)
Hem config1 ve config2 tam olarak aynı tabloya başvurur. Bir değişken üzerinden yapılan değişiklikler diğeri üzerinden anında görünür ve tüm uygulamanızda paylaşılan bir durum (state) sağlar.
Singleton deseni Factory deseninden farklıdır: Factory yeni nesneler oluştururken, Singleton tutarlı bir duruma sahip tek bir paylaşılan örnek garanti eder.
Kendin dene
-- main.lua - Singleton desenini göster
-- Girdileri oku
local newMusicVolume = tonumber(io.read())
local newDifficulty = io.read()
-- YAPILACAK: GameSettings modülünü bir değişkene aktar (örneğin, settings1)
-- YAPILACAK: GameSettings modülünü TEKRAR FARKLI bir değişkene aktar (örneğin, settings2)
-- (Eğer Singleton doğru çalışıyorsa, her iki değişken de aynı tabloyu referans alır!)
-- YAPILACAK: İLK değişkeni kullanarak:
-- - Müzik sesini newMusicVolume olarak ayarla
-- - Zorluğu newDifficulty olarak ayarla
-- YAPILACAK: Ayarları yazdırmak için İKİNCİ değişkeni kullan
-- Her birini kendi satırında yazdır: musicVolume, sfxVolume, difficulty
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