Menu
Coddy logo textTech

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)
end

Artı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ıyor

logMessage 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.

challenge icon

Görev

Kolay

Farklı ö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) metodu Charging {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) metodu Transferring {amount} from account {accountId} yazdırmalıdır.
  • main.lua: Herhangi bir ödeme nesnesini ve bir tutarı kabul eden, ardından üzerinde handlePayment(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:

  1. Bir kredi kartı numarası (ör. 4532-1234-5678)
  2. Bir banka hesabı kimliği (ör. ACC-9876)
  3. 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-5555

Bu 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
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