Ortak Arayüz
Coddy'nin Lua Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 40 / 70.
Duck typing, ilgisiz sınıfların yöntem adlarını paylaşmaları durumunda birlikte çalışabileceğini gösterdi. Bu fikir, güçlü bir tasarım kavramına yol açar: ortak arayüz. Birden fazla sınıfı aynı yöntem imzalarına sahip olacak şekilde bilinçli olarak tasarladığında, birbirinin yerine kullanılabilen bileşenler oluşturursun.
Bir günlük kaydı sistemi oluşturduğunuzu düşünün. Mesajları farklı hedeflere göndermek isteyebilirsiniz: bir dosyaya, ekrana veya hatta bir ağa. Her biri için ayrı kod yazmak yerine, tüm çıktı sınıflarınızı aynı :write() yöntemini uygulayacak şekilde tasarlarsınız:
local LogFile = {}
LogFile.__index = LogFile
function LogFile:new(filename)
local obj = {filename = filename}
setmetatable(obj, LogFile)
return obj
end
function LogFile:write(message)
print("[FILE:" .. self.filename .. "] " .. message)
end
local Screen = {}
Screen.__index = Screen
function Screen:new()
local obj = {}
setmetatable(obj, Screen)
return obj
end
function Screen:write(message)
print("[SCREEN] " .. message)
endArtık mesajları çıktı olarak vermesi gereken herhangi bir kod, her iki türü de kabul edebilir:
local function logMessage(output, msg)
output:write(msg)
end
local file = LogFile:new("app.log")
local screen = Screen:new()
logMessage(file, "Starting up") -- [FILE:app.log] Başlatılıyor
logMessage(screen, "Starting up") -- [SCREEN] BaşlatılıyorlogMessage işlevi hangi sınıfı aldığını bilmez veya önemsemez. Yalnızca bir :write() yöntemini bekler. Bu, kodunuzu esnek hâle getirir. Mevcut işlevleri değiştirmeden daha sonra yeni çıktı türleri ekleyebilirsiniz.
Görev
KolayFarklı ödeme yöntemlerinin birbirinin yerine kullanılabildiği bir ödeme işleme sistemi oluşturalım! Ortak bir arayüzü, yani :process(amount) metodunu paylaşan, birbiriyle tamamen ilgisiz iki ödeme sınıfı oluşturacaksın. Böylece ödemeleri işleyen herhangi bir kod, aralarındaki farkı bilmeden her iki türle de çalışabilecek.
Kodunu üç dosyaya ayıracaksın:
CreditCard.lua::new(cardNumber)yapıcısına sahip ve kart numarasını saklayan bir ödeme sınıfı.:process(amount)metoduCharging {amount} to card {cardNumber}yazdırmalıdır.BankTransfer.lua::new(accountId)yapıcısına sahip, tamamen ayrı bir ödeme sınıfı.:process(amount)metoduTransferring {amount} from account {accountId}yazdırmalıdır.main.lua: Herhangi bir ödeme nesnesini ve bir tutarı kabul eden, ardından üzerindehandlePayment(paymentMethod, amount)çağrısı yapan:process(amount)adlı bir fonksiyon oluştur. Bu fonksiyonun bir kredi kartıyla mı yoksa banka havalesiyle mi çalıştığını bilmesine gerek yoktur. Yalnızca nesnenin bir:process()metoduna sahip olmasını bekler.
Üç girdi alacaksın:
- Bir kredi kartı numarası (ör.
4532-1234-5678) - Bir banka hesabı kimliği (ör.
ACC-9876) - Bir ödeme tutarı (ör.
150)
Ana dosyanda, ilk iki girdiyi kullanarak her ödeme türünden bir örnek oluştur. Ardından verilen tutarı her iki ödeme yöntemiyle işlemek için handlePayment fonksiyonunu kullan: önce kredi kartı, ardından banka havalesi.
Örneğin girdiler 1111-2222-3333, ACC-5555 ve 75 ise çıktı şöyle olmalıdır:
Charging 75 to card 1111-2222-3333
Transferring 75 from account ACC-5555Bu tasarımın güzelliği, handlePayment fonksiyonunun :process() uygulayan herhangi bir nesneyle çalışabilmesidir. Yarın bir PayPal sınıfı ekleyebilirsin; :process(amount) metoduna sahip olduğu sürece mevcut fonksiyonunla hiçbir değişiklik yapmadan çalışır!
Kendin dene
-- Ödeme sınıflarını içe aktar
local CreditCard = require('CreditCard')
local BankTransfer = require('BankTransfer')
-- Girdileri oku
local cardNumber = io.read()
local accountId = io.read()
local amount = tonumber(io.read())
-- TODO: Herhangi bir ödeme nesnesini kabul eden handlePayment fonksiyonunu oluştur
-- ve bir tutar, ardından üzerinde :process(amount) çağırır
-- TODO: Girdileri kullanarak CreditCard ve BankTransfer örnekleri oluştur
-- TODO: Tutarı her iki ödeme yöntemiyle işlemek için handlePayment kullan
-- Önce kredi kartı, sonra banka havalesi
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