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ı amacı belirtir, ancak erişimi gerçekten engellemez. Herkes yine de player._health = 999 yazabilir ve bu çalışır. Gerçek gizlilik için Lua farklı bir yaklaşım sunar: verileri self üzerinde değil, oluşturucunun içindeki yerel değişkenlerde saklamak.

Temel fikir, bir işlevin içindeki yerel değişkenlere yalnızca o işlevin ve onun içinde tanımlanan işlevlerin erişebileceğidir. Buna kapanış denir:

local Counter = {}
Counter.__index = Counter

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

Bu örnekte count yalnızca :new() işlevinin içinde bulunur. obj içinde depolanmadığından, ona dışarıdan erişmenin bir yolu yoktur: myCounter.count, nil döndürür ve bunu atlatmak için alt çizgiyle başlayan bir alan da yoktur.

count değişkeni closure kapsamı içinde bulunur. Harici koddan tamamen gizli kalır. (Yazıldığı hâliyle henüz hiçbir şey count'u yakalamıyor; sonraki derste yapıcı içinde onun üzerine kapanan metotlar ekleyeceksin, böylece nesne var olduğu sürece kalıcı olacaktır.) Yalnızca nazik bir öneri olan self._count'un aksine, bu yaklaşım verileri gerçekten erişilemez hâle getirir.

Elbette, gizli verilerle hiçbir zaman etkileşime geçemiyorsanız bunlar kullanışlı değildir. Sonraki derste, bu özel değişkenleri okuyup değiştirebilen yöntemleri oluşturucunun içinde nasıl tanımlayacağınızı öğrenecek ve gerçek kapsüllemeyi korurken kontrollü erişim sağlayacaksınız.

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 nesnenin dışından gerçekten erişilemez hâle getirir.

Kodunu iki dosyaya ayıracaksın:

  • SecretKeeper.lua: Sırrın self üzerinde değil, oluşturucunun içindeki yerel bir değişkende saklandığı bir sınıf oluştur. :new(secretValue) oluşturucusu, sırrı yalnızca closure içinde var olan bir yerel değişkende saklamalıdır. Şimdilik nesnenin bu sırra erişmesinin herhangi bir yolu olmayacak (bu, sonraki derste ele alınacak!), ancak nesnenin çalıştığını doğrulayabilmemiz için örnek üzerinde name değerine ayarlanmış herkese açık bir "Keeper" alanı da saklamalısın.
  • main.lua: SecretKeeper modülünü içe aktar ve girdiden bir sır değeri oku. Bu sırla bir SecretKeeper örneği oluştur. Ardından üç şey yazdırarak sırrın gerçekten gizli olduğunu göster:
    • Keeper'ın name alanı (Keeper yazdırılmalı)
    • keeper.secret alanına erişmeye çalıştığında ne olduğu (nil olmalı)
    • keeper._secret alanına erişmeye çalıştığında ne olduğu (bu da nil olmalı)

Bir girdi alacaksın:

  1. Saklanacak sır değeri (ör. TopSecret123)

Çıktın, herkese açık alan çalışırken sırrın tamamen gizli olduğunu gösteren üç satırdan oluşmalı:

Name: Keeper
secret: nil
_secret: nil

Girdi olarak hangi sırrı verirsen ver, çıktının aynı olması gerekir; çünkü ona erişmenin hiçbir yolu yoktur! Oluşturucunun içindeki yerel değişken dış dünyadan görünmez. Bu, closure tabanlı gizliliğin alt çizgi adlandırma kuralından temelde farklı olduğunu kanıtlar.

Örneğin girdi MyPassword ise çıktı yine şöyle olmalı:

Name: Keeper
secret: nil
_secret: nil

Kendin dene

-- SecretKeeper modülünü yükle
local SecretKeeper = require('SecretKeeper')

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

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

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

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

-- TODO: keeper._secret'e erişildiğinde ne olduğunu yazdır (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

Kendi başına pratik yap: Online Lua derleyicisi