0Pricing
Lua Academy · Ders

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

Karışı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

  1. __index Zincirleme ile Tekli Kalıtım
  2. Üst Sınıf Yöntemlerini super ile Çağırma
  3. Karışım Örüntüleri
  4. Geçersiz Kılma ve Çok Biçimlilik
← Lua Academy Sayfasına Dön