Kapanışlarla Kapsülleme
Özel durumu kapanış tabanlı nesne örüntüleriyle gizleyin.
Kapanışlarla Kapsülleme, CoddyKit'te ücretsiz bir Lua Academy dersidir. Bu, 4 dersinin 4. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, Lua Academy öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. Lua Academy kursu toplamda 4 dersten oluşur.
Kapanış Tabanlı Nesneler
Üst veri tablosu tabanlı OOP'ye bir alternatif: durumu gizlemek için kapanış kullanın. Nesne bir işlevler tablosudur; tüm işlevler özel değişkenleri kapsar. Üst veri tablosu gerekmez. Dışarıdan erişilemeyen gerçekten özel bir durum elde edilir.
local function makeCounter(start)
local count = start or 0 -- truly private
return {
increment = function() count=count+1 end,
decrement = function() count=count-1 end,
get = function() return count end,
reset = function() count=0 end,
}
end
local c = makeCounter(10)
c.increment(); c.increment()
print(c.get()) -- 12
print(c.count) -- nil (truly private!)Özel ve Genel
Kapanışlarda özel ve genel arasındaki ayrım kesindir: kapanışlar üst değeri (özel) paylaşır, dış kod yalnızca döndürülen tabloyu (genel) görür. Genel API üzerinden geçmeden özel değişkenlere erişmenin bir yolu yoktur.
local function makeAccount(initial)
local balance = initial
local transactions = {}
local function record(type, amount)
transactions[#transactions+1] = {type=type,amount=amount}
end
return {
deposit = function(n) record("D",n); balance=balance+n end,
withdraw = function(n)
if n>balance then error("insufficient funds") end
record("W",n); balance=balance-n
end,
balance = function() return balance end,
history = function() return transactions end,
}
endPaylaşılan Kapanışlar
Aynı döndürülen tablodaki birden çok işlev, aynı üst değerleri paylaşır. Durum, genel olarak açığa çıkarılmadan yöntemler arasında böyle paylaşılır. Tüm yöntemler aynı özel değişkenleri görür.
local function makeQueue()
local items = {} -- shared by all methods
local size = 0
return {
enqueue = function(v) size=size+1; items[size]=v end,
dequeue = function()
if size==0 then return nil end
local head=1
while items[head]==nil do head=head+1 end
local v=items[head]; items[head]=nil; return v
end,
isEmpty = function() return size==0 end,
count = function() return size end,
}
endKapanışlar ve Üst Veri Tabloları
Kapanışlar: gerçekten özel durum, üst veri tablosu ek yükü yok, her örneğin kendi işlev kopyaları vardır (daha fazla bellek). Üst veri tabloları: paylaşılan yöntemler (daha az bellek), hata ayıklama araçlarıyla incelenebilir ve kalıtımı destekler. Seçiminizi gizlilik gereksinimlerine ve örnek sayısına göre yapın.
-- Closure: per-instance functions (more memory)
local function makePoint(x,y)
return {
x = function() return x end,
y = function() return y end,
distance = function()
return math.sqrt(x*x+y*y)
end
}
end
-- Metatable: shared methods (less memory)
-- local Point = {}; Point.__index = Point
-- function Point.new(x,y) return setmetatable({x=x,y=y},Point) endDeğiştirilebilir Kapanışlar
Değiştirilebilir değişkenleri kapsayan kapanışlar, hiç tablo kullanmadan durum bilgisi taşıyan nesneler oluşturmanızı sağlar. Tek bir kapanış durumu tutabilir ve sonuçları hesaplayabilir.
local function makeAccumulator()
local sum, count = 0, 0
return {
add = function(n) sum=sum+n; count=count+1 end,
mean = function()
return count>0 and sum/count or 0
end,
total = function() return sum end,
n = function() return count end,
}
end
local acc = makeAccumulator()
for _, v in ipairs({10,20,30,40,50}) do
acc.add(v)
end
print(acc.total(),acc.mean(),acc.n()) -- 150 30.0 5Doğrulamalı Yapıcı
Kapanış tabanlı yapıcılarda doğrulama bir yöntemde değil, fabrika işlevinde yapılır. Geçersiz girdiler, herhangi bir nesne oluşturulmadan önce fabrikanın nil veya hata döndürmesine neden olur.
local function makeRange(lo, hi)
assert(lo<=hi,"lo must be <= hi")
return {
contains = function(v) return v>=lo and v<=hi end,
clamp = function(v) return math.max(lo,math.min(hi,v)) end,
lo = function() return lo end,
hi = function() return hi end,
span = function() return hi-lo end,
}
end
local r = makeRange(0,100)
print(r.contains(50)) -- true
print(r.clamp(150)) -- 100Kapanışlarla Olaylar
Kapanışlarla uygulanan bir olay yayıcıda işleyiciler listesi özeldir; add/remove/emit genel API'yi oluşturur.
local function makeEmitter()
local handlers = {}
return {
on = function(event, fn)
handlers[event] = handlers[event] or {}
handlers[event][#handlers[event]+1] = fn
end,
emit = function(event, ...)
for _, fn in ipairs(handlers[event] or {}) do
fn(...)
end
end,
off = function(event) handlers[event] = {} end,
}
end
local emitter = makeEmitter()
emitter.on("data", function(v) print("Got:", v) end)
emitter.emit("data", 42) -- Got: 42Kapanışla Anımsatma
Kapanış kullanan bir anımsama sarmalayıcısında önbellek özeldir, sarılan işlev özeldir ve yalnızca anımsanmış sürüm döndürülür.
local function memoize(fn)
local cache = {}
return function(...)
local key = table.concat({...}, ",")
if cache[key] == nil then
cache[key] = fn(...)
end
return cache[key]
end
end
local expensiveFib
expensiveFib = memoize(function(n)
if n<=1 then return n end
return expensiveFib(n-1)+expensiveFib(n-2)
end)
for i=0,10 do io.write(expensiveFib(i).." ") end
print()Kapanış Nesnelerini Genişletme
Özgün nesnenin yöntemlerini çağıran yeni bir nesne oluşturarak kapanış tabanlı bir nesneyi genişletebilirsiniz. Bu, kalıtımdan çok sarmalamaya benzer — özgün nesneye yetkilendirme yapılır.
local function makeTimedCounter(start)
local base = makeCounter and makeCounter(start) or (function()
local c=start or 0
return {inc=function()c=c+1 end,get=function()return c end}
end)()
local callCount = 0
return {
increment = function()
callCount=callCount+1
base.inc()
end,
get = base.get,
calls = function() return callCount end,
}
endKapanışlar Ne Zaman Kullanılmalı
Şu durumlarda kapanış tabanlı OOP kullanın: gerçekten özel ve güvenli tutulması gereken bir duruma ihtiyaç duyuyorsanız, az sayıda örneğiniz varsa (bellek önemli değilse) veya işlevsel biçemde kod yazıyorsanız. Şu durumlarda üst veri tablolarını kullanın: kalıtıma, çok sayıda örneğe ihtiyaç duyuyorsanız veya OOP kitaplıklarıyla tümleştirmek istiyorsanız.
-- Guideline summary:
-- Closures: true privacy, no metatable, self-contained
-- Metatables: shared methods, inheritance, instanceof checks
-- Rule of thumb:
-- < 100 instances with private state -> closures
-- > 100 instances OR need inheritance -> metatables
print("Both patterns are valid Lua OOP.")Hızlı Kontrol
Kapanış tabanlı nesnelerin üst veri tablosu tabanlı nesnelere göre temel avantajı nedir?
Özet: Kapsülleme için Kapanışlar
Özet:
- Kapanış kalıbı: fabrika işlevi bir yöntemler tablosu döndürür; durum üst değerdir
- Gerçekten özeldir: üst değerlere dışarıdan erişmenin yolu yoktur
- Döndürülen tüm yöntemler aynı özel üst değerleri paylaşır
- Ödünleşim: örnek başına daha fazla bellek karşılığında daha iyi gizlilik
- Güvenlik açısından kritik kod veya işlevsel biçemli tasarımlar için kullanın
Sıkça Sorulan Sorular
“Kapanışlarla Kapsülleme” dersi ücretsiz mi?
Evet — “Kapanışlarla Kapsülleme” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve Lua Academy kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. Lua Academy kursu toplamda 4 dersten oluşur.
“Kapanışlarla Kapsülleme” dersinde ne öğreneceğim?
Özel durumu kapanış tabanlı nesne örüntüleriyle gizleyin. Lua Academy ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.
Lua Academy öğrenmeye başlamak için deneyim gerekli mi?
Önceden deneyim gerekmez. CoddyKit'te Lua Academy, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 4. dersidir.
“Kapanışlarla Kapsülleme” dersi ne kadar sürer?
Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.
Bu Lua Academy dersinde kod yazıp çalıştırabilir miyim?
Evet. Her Lua Academy dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.
Bu kursun tüm dersleri
- Üst Tablolarla Sınıflar
- Oluşturucular ve new()
- Örnek Yöntemleri ve self
- Kapanışlarla Kapsülleme