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
endBu ö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.
Görev
KolayClosure'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ınselfü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 üzerindenamedeğ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
namealanı (Keeperyazdırılmalı) keeper.secretalanına erişmeye çalıştığında ne olduğu (nilolmalı)keeper._secretalanına erişmeye çalıştığında ne olduğu (bu danilolmalı)
- Keeper'ın
Bir girdi alacaksın:
- 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: nilGirdi 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: nilKendin 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>")
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
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şisiKendi başına pratik yap: Online Lua derleyicisi