Pola Mixin
Gabungkan perilaku dengan menyalin metode dari beberapa tabel sumber.
Pola Mixin adalah pelajaran Lua Academy gratis di CoddyKit. Ini adalah pelajaran 3 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Lua Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Lua Academy mencakup 4 pelajaran total.
Apa Itu Campuran?
Campuran adalah tabel berisi metode yang dapat disalin ke beberapa kelas. Berbeda dari pewarisan, campuran menambahkan perilaku tanpa membentuk hubungan induk-anak. Sebuah kelas dapat menggabungkan perilaku dari beberapa campuran.
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()Beberapa Campuran
Terapkan beberapa campuran ke satu kelas untuk menyusun perilaku kompleks dari bagian-bagian sederhana. Ini adalah komposisi horizontal—setiap campuran berdiri sendiri.
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"}))Konflik Campuran
Ketika dua campuran mendefinisikan nama metode yang sama, campuran yang diterapkan terakhir akan menang. Selesaikan konflik secara eksplisit dengan memilih versi campuran yang ingin dipertahankan, atau bungkus keduanya agar dapat memanggil kedua versi.
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()Pembantu include()
Fungsi pembantu membuat penerapan campuran lebih rapi: include(Class, Mixin) menyalin metode campuran ke dalam kelas dan melewati bidang yang sudah ada, sehingga metode yang ada tidak tertimpa.
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)Campuran dengan Status
Campuran yang memerlukan status per instans menginisialisasinya dalam fungsi init campuran. Konstruktor kelas memanggil fungsi init campuran untuk menyiapkan status setiap campuran pada instans.
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")Modul Campuran
Kemas perilaku campuran dalam berkas modul terpisah. Minta modul tersebut di modul kelas, lalu terapkan. Dengan begitu, setiap aspek perilaku berada dalam berkasnya sendiri dan basis kode menjadi lebih teratur.
-- 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)Campuran Berbasis Peran
Tetapkan peran pada objek saat program berjalan dengan menerapkan fungsi campuran secara selektif. Dengan demikian, perilaku dapat dikonfigurasi per instans, bukan per kelas.
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()Memeriksa Penerapan Campuran
Lacak campuran yang telah diterapkan pada suatu kelas menggunakan himpunan. Ini mencegah penerapan ganda dan memungkinkan pemeriksaan kemampuan suatu kelas.
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) -- trueCampuran vs Pewarisan vs Komposisi
Tiga gaya komposisi: pewarisan (adalah-sebuah, hierarki ketat), campuran (menyalin metode, datar), dan komposisi (memiliki-sebuah, delegasi). Pilih berdasarkan hubungannya: hewan IS-A makhluk (pewarisan), makhluk CAN terbang (campuran), mobil HAS mesin (komposisi).
-- 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")Templat Campuran
Templat campuran standar: tabel campuran memiliki metode, _init opsional untuk status per instans, dan bidang nama untuk mendeteksi konflik. Mengikuti pola yang konsisten membuat campuran dapat disusun di berbagai proyek.
-- 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")Pertanyaan tentang Campuran
Bagaimana cara menerapkan campuran ke sebuah kelas?
Ringkasan: Pola Campuran
Campuran menyalin metode dari tabel sumber ke kelas target, sehingga menyusun perilaku tanpa pewarisan. Gunakan campuran untuk aspek lintas fungsi seperti serialisasi, pencatatan, dan penanganan peristiwa.
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Pola Mixin” gratis?
Ya — teks lengkap “Pola Mixin” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Lua Academy, upgrade ke CoddyKit PRO. Kursus Lua Academy mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Pola Mixin”?
Gabungkan perilaku dengan menyalin metode dari beberapa tabel sumber. Kamu berlatih Lua Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai Lua Academy?
Tidak diperlukan pengalaman sebelumnya. Lua Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 3 dari 4.
Berapa lama pelajaran “Pola Mixin” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran Lua Academy ini?
Ya. Setiap pelajaran Lua Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Pewarisan Tunggal dengan Chaining __index
- Memanggil Metode Induk dengan super
- Pola Mixin
- Penggantian Metode dan Polimorfisme