Menu
Coddy logo textTech

Basit Mixin'ler

Coddy'nin Lua Journey'sinin Object Oriented Programming bölümünün bir parçası — ders 51 / 70.

Kompozisyon, nesneleri diğer nesnelerin içine koymanıza olanak tanır. Peki ya davranışı ilişkisiz sınıflar arasında paylaşmak isterseniz?

Bir Player ve bir MenuItem'ın her ikisinin de bir :describe() metoduna ihtiyacı olabilir, ancak ortak bir üst sınıfı paylaşmazlar. İşte mixin'ler burada devreye girer.

Bir mixin, basitçe fonksiyonlar içeren bir tablodur. Bu fonksiyonları bir sınıfa kopyalayarak "mix" edersiniz (karıştırırsınız):

local Printable = {}

function Printable:describe()
    print("Object: " .. tostring(self))
end

function Printable:log(message)
    print("[LOG] " .. message)
end

Bu mixin'i bir sınıfa uygulamak için, mixin tablosundaki her bir fonksiyonu sınıf tablosuna kopyalarsınız:

local function applyMixin(class, mixin)
    for key, value in pairs(mixin) do
        class[key] = value
    end
end

local Player = {}
Player.__index = Player

applyMixin(Player, Printable)  -- Artık Player :describe() ve :log() metotlarına sahip

Mixin'i uyguladıktan sonra, herhangi bir Player örneği bu metotları sanki doğrudan sınıf üzerinde tanımlanmışlar gibi çağırabilir:

local p = setmetatable({}, Player)
p:log("Player created")  -- [LOG] Oyuncu oluşturuldu

Kalıtımın aksine, mixin'ler bir ebeveyn-çocuk ilişkisi oluşturmaz. Sadece fonksiyonları bir tablodan diğerine kopyalıyorsunuz.

Bu, mixin'leri; günlükleme, serileştirme veya açıklama yöntemleri gibi yardımcı davranışları, aksi takdirde hiçbir ortak noktası olmayan sınıflar arasında paylaşmak için mükemmel kılar.

challenge icon

Görev

Kolay

Mixin'leri kullanarak bir etiketleme sistemi oluşturalım! Herhangi bir sınıfa uygulanabilen, nesnelere bir etiket koleksiyonunu yönetme yeteneği kazandıran bir Taggable mixin'i oluşturacaksınız; bu, öğeleri, gönderileri veya etiket gerektiren herhangi bir varlığı kategorize etmek için kullanışlıdır.

Kodunuzu üç dosya halinde düzenleyeceksiniz:

  • Taggable.lua: İki metot içeren bir mixin tablosu oluşturun:
    • :addTag(tag)self.tags tablosuna bir etiket ekler (tablonun var olduğunu varsayar)
    • :listTags() — tüm etiketleri Tags: tag1, tag2, tag3 formatında yazdırır (boşsa Tags: none yazdırır)
  • Article.lua: Başlığı saklayan ve boş bir tags tablosu başlatan :new(title) kurucusuna sahip bir Article sınıfı oluşturun. Article örneklerine etiketleme yetenekleri kazandırmak için Taggable mixin'ini uygulayın. Makalenin başlığını döndüren bir :getTitle() metodu ekleyin.
  • main.lua: applyMixin yardımcı fonksiyonunu buraya yazın (bunu Article.lua içinde require aracılığıyla kullanacaksınız). Ardından bir makale başlığı ve iki etiket için girdileri okuyun. Bir Article oluşturun, her iki etiketi de ona ekleyin, başlığı yazdırın ve tüm etiketleri listeleyin.

Üç girdi alacaksınız:

  1. Makale başlığı (bir dize)
  2. Eklenecek ilk etiket (bir dize)
  3. Eklenecek ikinci etiket (bir dize)

Çıktınız, makalenin başlığını ve ardından etiketlerini göstermelidir:

Title: {title}
Tags: {tag1}, {tag2}

Örneğin, girdiler Lua Basics, programming ve tutorial ise çıktı şöyle olmalıdır:

Title: Lua Basics
Tags: programming, tutorial

Unutmayın: mixin metotları çalışır çünkü Article örnekleri, mixin metotlarının üzerinde işlem yapabileceği bir tags tablosuna sahiptir. Mixin bu tabloyu oluşturmaz; bunu Article kurucunuz yapar. Mixin sadece paylaşılan davranışı sağlar!

Kopya kağıdı

Bir mixin, ebeveyn-çocuk ilişkisi oluşturmadan ilgisiz sınıflar arasında paylaşılabilen fonksiyonlar içeren bir tablodur.

Bir mixin oluşturmak için metotlar içeren bir tablo tanımlayın:

local Printable = {}

function Printable:describe()
    print("Object: " .. tostring(self))
end

function Printable:log(message)
    print("[LOG] " .. message)
end

Bir mixin'i bir sınıfa uygulamak için, fonksiyonlarını sınıf tablosuna kopyalayın:

local function applyMixin(class, mixin)
    for key, value in pairs(mixin) do
        class[key] = value
    end
end

local Player = {}
Player.__index = Player

applyMixin(Player, Printable)

Mixin uygulandıktan sonra, örnekler (instances) mixin metotlarını çağırabilir:

local p = setmetatable({}, Player)
p:log("Player created")  -- [LOG] Player created

Mixin'ler; günlükleme (logging), serileştirme (serialization) veya etiketleme (tagging) gibi yardımcı davranışları, kalıtım paylaşmayan sınıflar arasında paylaşmak için idealdir.

Kendin dene

-- Etiketleme sistemi için ana dosya
local Taggable = require('Taggable')
local Article = require('Article')

-- YAPILACAK: applyMixin fonksiyonunu uygula
-- Bu fonksiyon, bir mixin tablosundaki tüm metotları bir hedef tabloya kopyalamalıdır
function applyMixin(target, mixin)
    -- YAPILACAK: Mixin üzerinde döngü kurun ve her metodu hedefe kopyalayın
end

-- Girdileri oku
local title = io.read()
local tag1 = io.read()
local tag2 = io.read()

-- YAPILACAK: Verilen başlıkla bir Article oluşturun

-- YAPILACAK: Makaleye her iki etiketi de ekleyin

-- YAPILACAK: Başlığı şu formatta yazdırın: Title: {title}

-- YAPILACAK: listTags metodunu kullanarak tüm etiketleri listeleyin
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Object Oriented Programming bölümündeki tüm dersler