Karışım Örüntüleri
Birden çok kaynak tablodan yöntemleri kopyalayarak davranışları birleştirin.
Karışım Örüntüleri, CoddyKit'te ücretsiz bir Lua Academy dersidir. Bu, 4 dersinin 3. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, Lua Academy öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. Lua Academy kursu toplamda 4 dersten oluşur.
Karışım Nedir?
Karışım, birden fazla sınıfa kopyalanabilen yöntemlerden oluşan bir tablodur. Kalıtımdan farklı olarak karışımlar, bir üst sınıf-alt sınıf ilişkisi kurmadan davranış ekler. Bir sınıf, birden fazla karışımdaki davranışları birleştirebilir.
local Flyable={}
function Flyable:fly()
print(self.name.." is flying!")
end
function Flyable:land()
print(self.name.." landed.")
end
local Bird={} Bird.__index=Bird
-- Mix in Flyable
for k,v in pairs(Flyable) do Bird[k]=v end
function Bird.new(name)
return setmetatable({name=name},Bird)
end
Bird.new("Eagle"):fly()Birden Fazla Karışım
Basit parçaları bir araya getirerek karmaşık bir davranış oluşturmak için tek bir sınıfa birden fazla karışım uygulayabilirsiniz. Bu, yatay birleştirmedir; her karışım bağımsızdır.
local Serializable={}
function Serializable:toCSV(fields)
local row={}
for _,f in ipairs(fields) do row[#row+1]=tostring(self[f]) end
return table.concat(row,",")
end
local Loggable={}
function Loggable:log(msg)
print("["..os.date("%H:%M").."]["..self.name.."] "..msg)
end
local Entity={} Entity.__index=Entity
for k,v in pairs(Serializable) do Entity[k]=v end
for k,v in pairs(Loggable) do Entity[k]=v end
function Entity.new(n,v) return setmetatable({name=n,value=v},Entity) end
local e=Entity.new("item",42)
e:log("created"); print(e:toCSV({"name","value"}))Karışım Çakışmaları
İki karışım aynı yöntem adını tanımladığında, en son uygulanan kazanır. Hangi karışımın sürümünü koruyacağınızı açıkça seçerek veya her ikisini de çağıracak şekilde sarmalayarak çakışmaları çözün.
local A={speak=function(self) print(self.name.." (A)") end}
local B={speak=function(self) print(self.name.." (B)") end}
local C={} C.__index=C
for k,v in pairs(A) do C[k]=v end
for k,v in pairs(B) do C[k]=v end -- B.speak overwrites A.speak
-- Explicit resolution:
local origA, origB = A.speak, B.speak
function C:speak() origA(self); origB(self) end -- call both
local c=setmetatable({name="X"},C)
c:speak()include() Yardımcısı
Bir yardımcı işlev, karışımların uygulanmasını daha anlaşılır hâle getirir: include(Class, Mixin), karışım yöntemlerini sınıfa kopyalar ve zaten var olan alanları atlar; böylece mevcut yöntemlerin üzerine yazılmaz.
local function include(cls, mixin)
for k, v in pairs(mixin) do
if cls[k] == nil then
cls[k] = v
end
end
return cls
end
local Comparable={
equals=function(a,b) return a:compareTo(b)==0 end,
lt=function(a,b) return a:compareTo(b)<0 end,
}
local Temp={} Temp.__index=Temp
include(Temp, Comparable)
function Temp.new(c) return setmetatable({c=c},Temp) end
function Temp:compareTo(other) return self.c-other.c end
local a,b=Temp.new(100),Temp.new(50)
print(b.lt and b:lt(a)) -- true (b < a)Durum İçeren Karışım
Örnek başına duruma ihtiyaç duyan karışımlar, bu durumu karışımın başlatma işlevinde başlatır. Sınıf oluşturucusu, her karışımın başlatma işlevini çağırarak örnekteki ilgili durumu kurar.
local Observable={}
function Observable._init(self)
self._listeners={}
end
function Observable:on(event,fn)
self._listeners[event]=self._listeners[event] or {}
self._listeners[event][#self._listeners[event]+1]=fn
end
function Observable:emit(event,...)
for _,fn in ipairs(self._listeners[event] or {}) do fn(...) end
end
local Button={} Button.__index=Button
for k,v in pairs(Observable) do Button[k]=v end
function Button.new(label)
local self=setmetatable({label=label},Button)
Observable._init(self)
return self
end
local btn=Button.new("OK")
btn:on("click",function() print("Clicked!") end)
btn:emit("click")Karışım Modülleri
Karışım davranışlarını ayrı modül dosyalarında paketleyin. Bunları sınıf modülünde gerektirin ve uygulayın. Böylece her davranışla ilgili sorumluluk kendi dosyasında kalır ve kod tabanı düzenli olur.
-- In a real project:
-- local Loggable = require("mixins.loggable")
-- local Cacheable = require("mixins.cacheable")
-- local MyClass = {}
-- for k,v in pairs(Loggable) do MyClass[k]=v end
-- for k,v in pairs(Cacheable) do MyClass[k]=v end
local TimestampMixin={}
function TimestampMixin:setCreated() self.createdAt=os.time() end
function TimestampMixin:age() return os.time()-self.createdAt end
local Record={} Record.__index=Record
for k,v in pairs(TimestampMixin) do Record[k]=v end
function Record.new(data)
local self=setmetatable(data or {},Record)
self:setCreated()
return self
end
print(Record.new({}).createdAt>0)Role Dayalı Karışımlar
Karışım işlevlerini seçerek uygulayarak çalışma zamanında nesnelere roller atayın. Bu, davranışın sınıfa göre değil, örneğe göre yapılandırılmasını sağlar.
local Roles={}
Roles.admin={deleteUser=function(self) print(self.name.." deletes user") end}
Roles.editor={editPost=function(self) print(self.name.." edits post") end}
Roles.viewer={viewPost=function(self) print(self.name.." views post") end}
local User={} User.__index=User
function User.new(name,...)
local self=setmetatable({name=name},User)
for _,role in ipairs({...}) do
for k,v in pairs(Roles[role] or {}) do self[k]=v end
end
return self
end
local alice=User.new("Alice","admin","editor")
alice:deleteUser(); alice:editPost()Karışım Uygulamasını Denetleme
Bir sınıfa hangi karışımların uygulandığını bir kümeyle izleyin. Bu, aynı karışımın iki kez uygulanmasını önler ve sınıfın yeteneklerini incelemenize olanak tanır.
local function applyMixin(cls, mixin, name)
cls._mixins = cls._mixins or {}
if cls._mixins[name] then return end -- already applied
for k,v in pairs(mixin) do
if k~="_init" then cls[k]=cls[k] or v end
end
cls._mixins[name] = true
end
local Fly={fly=function(self) print(self.name.." flies") end}
local Bird={} Bird.__index=Bird
applyMixin(Bird,Fly,"Fly")
applyMixin(Bird,Fly,"Fly") -- no-op, already applied
print(Bird._mixins.Fly) -- trueKarışımlar ve Kalıtım ve Birleştirme
Üç birleştirme biçimi vardır: kalıtım (bir tür, katı hiyerarşi), karışımlar (yöntemleri kopyalama, düz yapı) ve birleştirme (bir şeye sahip olma, yetki devri). İlişkiye göre seçim yapın: hayvan CAN canlıdır (kalıtım), canlı uçabilir (karışım), araba HAS motora sahiptir (birleştirme).
-- Inheritance: "is-a"
-- local Dog = extends(Animal)
-- Mixin: "can-do"
-- include(Dog, Swimmable)
-- Composition: "has-a"
-- local Dog = {}
-- function Dog.new()
-- return {collar=Collar.new(),chip=Chip.new()}
-- end
print("Pick the right tool for the relationship")Karışım Şablonu
Standart bir karışım şablonunda karışım tablosu yöntemleri, örneğe özel durum için isteğe bağlı bir _init işlevini ve çakışma algılama için bir ad alanını içerir. Tutarlı bir kalıbı izlemek, karışımların projeler arasında birleştirilebilmesini sağlar.
-- Standard mixin template:
local EventMixin = {}
EventMixin._name = "EventMixin"
function EventMixin._init(self)
self._events = {}
end
function EventMixin:on(e, fn)
self._events[e] = self._events[e] or {}
self._events[e][#self._events[e]+1] = fn
end
function EventMixin:trigger(e, ...)
for _, fn in ipairs(self._events[e] or {}) do fn(...) end
end
-- return EventMixin
print("EventMixin ready for use")Karışım Sorusu
Bir karışımı bir sınıfa nasıl uygularsınız?
Özet: Karışım Kalıpları
Karışımlar, kalıtım kullanmadan davranışları birleştirerek yöntemleri kaynak tablodan hedef sınıfa kopyalar. Bunları serileştirme, günlük kaydı ve olay işleme gibi birden çok alanı ilgilendiren sorumluluklar için kullanın.
Sıkça Sorulan Sorular
“Karışım Örüntüleri” dersi ücretsiz mi?
Evet — “Karışım Örüntüleri” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve Lua Academy kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. Lua Academy kursu toplamda 4 dersten oluşur.
“Karışım Örüntüleri” dersinde ne öğreneceğim?
Birden çok kaynak tablodan yöntemleri kopyalayarak davranışları birleştirin. Lua Academy ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.
Lua Academy öğrenmeye başlamak için deneyim gerekli mi?
Önceden deneyim gerekmez. CoddyKit'te Lua Academy, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 3. dersidir.
“Karışım Örüntüleri” dersi ne kadar sürer?
Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.
Bu Lua Academy dersinde kod yazıp çalıştırabilir miyim?
Evet. Her Lua Academy dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.
Bu kursun tüm dersleri
- __index Zincirleme ile Tekli Kalıtım
- Üst Sınıf Yöntemlerini super ile Çağırma
- Karışım Örüntüleri
- Geçersiz Kılma ve Çok Biçimlilik