Menu
Coddy logo textTech

Gizlilik için Closure'lar

Coddy'nin Lua Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 44 / 70.

Adlandırma kuralları niyeti belirtir, ancak erişimi gerçekten engellemez. Herkes hala player._health = 999 yazabilir ve bu çalışır. Gerçek gizlilik için Lua farklı bir yaklaşım sunar: verileri self yerine yapıcı (constructor) içindeki yerel değişkenlerde saklamak.

Temel içgörü, bir fonksiyonun içindeki yerel değişkenlerin yalnızca o fonksiyonun içinden ve onun içinde tanımlanan herhangi bir fonksiyondan erişilebilir olmasıdır. Buna bir closure denir:

local Counter = {}
Counter.__index = Counter

function Counter:new()
    local count = 0  -- Gerçekten gizli! self üzerinde değil.
    
    local obj = {}
    setmetatable(obj, Counter)
    return obj
end

Bu örnekte, count yalnızca :new() fonksiyonunun içinde bulunur. obj içinde saklanmaz, bu yüzden ona dışarıdan erişmenin bir yolu yoktur—myCounter.count nil döndürür ve atlanacak alt çizgi önekli bir alan yoktur.

count değişkeni closure kapsamı içinde yer alır. Dış koddan tamamen gizli kalır. (Yazıldığı haliyle, henüz hiçbir şey count değişkenini yakalamaz; bir sonraki derste, yapıcı (constructor) içine onu kapsayan metodlar ekleyeceksiniz, böylece nesne var olduğu sürece o da kalıcı olacaktır.) Sadece nazik bir öneri olan self._countun aksine, bu yaklaşım veriyi gerçekten erişilemez kılar.

Elbette, gizli verilerle hiçbir zaman etkileşime giremiyorsanız, bu veriler yararlı değildir. Bir sonraki derste, bu private değişkenleri okuyabilen ve değiştirebilen metotları constructor içinde nasıl tanımlayacağınızı öğreneceksiniz; bu da size gerçek encapsulation'ı korurken kontrollü erişim sağlar.

challenge icon

Görev

Kolay

Closure'ları kullanarak gerçek veri gizliliğini gösteren bir SecretKeeper sınıfı oluşturalım! Önceki dersteki alt çizgi kuralının aksine, bu yaklaşım verileri nesne dışından gerçekten erişilemez hale getirir.

Kodunuzu iki dosya halinde düzenleyeceksiniz:

  • SecretKeeper.lua: Gizli değerin self üzerinde değil, yapıcı (constructor) içindeki yerel bir değişkende saklandığı bir sınıf oluşturun. :new(secretValue) yapıcısı, gizli değeri yalnızca closure içinde var olan yerel bir değişkende saklamalıdır. Şimdilik, nesnenin bu gizli değere erişmek için herhangi bir yolu olmayacak (bu bir sonraki derste gelecek!), ancak nesnenin çalıştığını doğrulayabilmemiz için örnek (instance) üzerinde "Keeper" olarak ayarlanmış genel bir name alanı da saklamalısınız.
  • main.lua: SecretKeeper modülünüzü dahil edin ve girdiden bir gizli değer okuyun. Bu gizli değerle bir SecretKeeper örneği oluşturun. Ardından üç şeyi yazdırarak gizli değerin gerçekten özel olduğunu kanıtlayın:
    • Keeper'ın name alanı (Keeper yazdırmalıdır)
    • keeper.secret değerine erişmeye çalıştığınızda ne olduğu (nil olmalıdır)
    • keeper._secret değerine erişmeye çalıştığınızda ne olduğu (bu da nil olmalıdır)

Bir girdi alacaksınız:

  1. Saklanacak gizli değer (örneğin, TopSecret123)

Çıktınız, genel alan çalışırken gizli değerin tamamen gizlendiğini gösteren üç satır olmalıdır:

Name: Keeper
secret: nil
_secret: nil

Hangi gizli değeri girerseniz girin çıktı aynı olacaktır; çünkü ona erişmenin hiçbir yolu yoktur! Yapıcı içindeki yerel değişken dış dünyaya görünmezdir. Bu, closure tabanlı gizliliğin alt çizgi adlandırma kuralından temelden farklı olduğunu kanıtlar.

Örneğin, girdi MyPassword ise, çıktı yine şu şekilde olmalıdır:

Name: Keeper
secret: nil
_secret: nil

Kendin dene

-- SecretKeeper modülünü dahil edin
local SecretKeeper = require('SecretKeeper')

-- Girdiden gizli değeri okuyun
local secretValue = io.read()

-- TODO: Gizli değer ile bir SecretKeeper örneği oluşturun

-- TODO: keeper nesnesinin name alanını yazdırın (format: "Name: <name>")

-- TODO: keeper.secret değerine erişildiğinde ne olduğunu yazdırın (format: "secret: <value>")

-- TODO: keeper._secret değerine erişildiğinde ne olduğunu yazdırın (format: "_secret: <value>")
quiz iconKendini test et

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