Lua Academy · Pelajaran

Corak Modul dan Amalan Terbaik

Gunakan corak local M = {} dan dedahkan API awam dengan kemas.

Pelajaran 4 daripada 412 langkah

Corak Modul dan Amalan Terbaik ialah pelajaran Lua Academy percuma di CoddyKit. Ini ialah pelajaran 4 daripada 4. Sebanyak 3 pelajaran dalam laluan pembelajaran ini boleh dibaca sepenuhnya secara percuma — selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan praktikal dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Lua Academy, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Lua Academy merangkumi sejumlah 4 pelajaran.

Corak M = {}

Corak modul Lua sejagat: isytiharkan jadual setempat, isi kandungannya, kemudian kembalikannya. Semua simbol awam diletakkan dalam M; semua pembantu persendirian ialah pemboleh ubah setempat biasa. Corak ini jelas, minimum dan berfungsi di mana-mana.

-- The canonical module pattern
local M = {}

-- Private helper (not exported)
local function validate(x)
  return type(x) == "number" and x >= 0
end

-- Public API
function M.sqrt(x)
  assert(validate(x), "expected non-negative number")
  return math.sqrt(x)
end

M.PI = math.pi

return M

Modul Rujukan Kendiri

Dalam modul, fungsi boleh memanggil fungsi modul lain sama ada melalui nama (M.foo()) atau sebagai pemboleh ubah setempat. Menggunakan pemboleh ubah setempat sedikit lebih pantas; menggunakan M.foo() membolehkan pengguna mengatasi M.foo dan menyebabkan panggilan dalaman menggunakan penggantian tersebut (tampalan monyet).

local M = {}

-- Option A: use M.foo inside (allows override)
function M.double(n) return M.multiply(n, 2) end
function M.multiply(a, b) return a * b end

-- Option B: use local function (faster, no override)
local function mul(a, b) return a * b end
function M.triple(n) return mul(n, 3) end

return M

Corak Singleton

Sebuah modul boleh bertindak sebagai singleton: ia mempunyai keadaan dalaman boleh ubah yang dikongsi oleh semua pemanggil. Oleh sebab require menyimpan modul dalam cache, semua panggilan require("mod") menerima objek yang sama dengan keadaan yang sama.

-- config.lua (singleton)
local M = {}
local _config = {env="dev", logLevel="info"}

function M.set(key, val)
  _config[key] = val
end

function M.get(key)
  return _config[key]
end

function M.load(t)
  for k,v in pairs(t) do _config[k]=v end
end

return M

-- All callers share the same config:

Modul sebagai Ruang Nama

Gunakan modul semata-mata sebagai ruang nama untuk mengelakkan pencemaran jadual global. Kumpulkan pemalar dan utiliti berkaitan di bawah satu nama, seperti pakej dalam bahasa lain.

-- constants.lua
local M = {
  HTTP = {
    OK=200, CREATED=201, NO_CONTENT=204,
    BAD_REQUEST=400, UNAUTHORIZED=401,
    NOT_FOUND=404, SERVER_ERROR=500,
  },
  COLORS = {RED="#FF0000", GREEN="#00FF00", BLUE="#0000FF"},
  MAX_RETRIES = 3,
  TIMEOUT_SEC = 30,
}
return M

-- local C = require("constants")
-- if status == C.HTTP.NOT_FOUND then ...

Modul Kilang

Modul yang mengeksport fungsi kilang dan bukannya jadual biasa. Kilang tersebut mencipta dan mengembalikan tika baharu dengan keadaan persendirian masing-masing. Ini ialah corak kelas pada peringkat modul.

-- logger.lua
local M = {}

function M.new(name, level)
  level = level or "info"
  local levels = {debug=1,info=2,warn=3,error=4}
  local self = {}
  
  function self.log(msgLevel, msg)
    if levels[msgLevel] >= levels[level] then
      print(string.format("[%s][%s] %s", name, msgLevel:upper(), msg))
    end
  end
  
  function self.info(msg)  self.log("info",  msg) end
  function self.warn(msg)  self.log("warn",  msg) end
  function self.error(msg) self.log("error", msg) end
  
  return self
end

return M

Fungsi Permulaan Modul

Sesetengah modul memerlukan konfigurasi sebelum digunakan. Sediakan fungsi M.init(config) yang menyimpan konfigurasi dalam keadaan persendirian modul. Ini membolehkan suntikan kebergantungan dan kebolehujiannya.

-- db.lua
local M = {}
local pool = nil

function M.init(config)
  pool = {
    host = config.host or "localhost",
    port = config.port or 5432,
    connections = {},
  }
  print("DB initialized:", pool.host, pool.port)
end

function M.query(sql)
  assert(pool, "call db.init() first")
  -- ... execute query
  return {}
end

return M

Modul Tidak Boleh Ubah

Halang pengguna daripada mengubah API modul secara tidak sengaja dengan menggunakan __newindex untuk menyekat semua penulisan. Ini amat berguna untuk modul pustaka kerana tampalan monyet yang tidak disengajakan boleh menyebabkan masalah.

local function freeze(t)
  return setmetatable({}, {
    __index = t,
    __newindex = function(_, k, _)
      error("module is read-only, cannot set: " .. tostring(k), 2)
    end
  })
end

local M = {}
function M.add(a, b) return a + b end
function M.sub(a, b) return a - b end

return freeze(M)

Mendokumentasikan dengan LDoc

Konvensyen lazim untuk mendokumentasikan modul Lua ialah komen gaya LDoc dengan awalan ---. Walaupun tidak dikuatkuasakan oleh bahasa tersebut, komen ini membolehkan alat penjanaan dokumentasi menghasilkan dokumen API secara automatik.

--- A utility module for string operations.
-- @module stringutils
local M = {}

--- Trim leading and trailing whitespace.
-- @param s string The input string.
-- @return string The trimmed string.
function M.trim(s)
  return s:match("^%s*(.-)%s*$")
end

--- Count occurrences of a substring.
-- @param str string The string to search.
-- @param sub string The substring to count.
-- @return number Count of occurrences.
function M.count(str, sub)
  local _, n = str:gsub(sub, "")
  return n
end

return M

Menguji Modul

Uji modul dengan memerlukannya dan menjalankan setiap fungsi. Gunakan pelaksana ujian ringkas atau busted (rangka kerja pengujian Lua). Simpan ujian dalam fail berasingan yang mencerminkan laluan modul.

-- test/test_stringutils.lua
local su = require("stringutils")

local function test(name, fn)
  local ok, err = pcall(fn)
  if ok then print("[PASS] " .. name)
  else   print("[FAIL] " .. name .. ": " .. err)
  end
end

test("trim removes spaces", function()
  assert(su.trim("  hello  ") == "hello")
end)

test("trim empty string", function()
  assert(su.trim("") == "")
end)

test("count occurrences", function()
  assert(su.count("banana", "a") == 3)
end)

Menggabungkan Modul

Sistem kompleks menggabungkan berbilang modul. Titik masuk utama memerlukan dan menyambungkan submodul. Pengasingan tanggungjawab ini memastikan setiap modul kekal fokus dan boleh diuji secara berasingan.

-- app.lua (main entry point)
local config = require("config")
local db     = require("db")
local server = require("server")

-- Configure from environment
config.load({
  dbHost = os.getenv("DB_HOST") or "localhost",
  port   = tonumber(os.getenv("PORT")) or 8080,
})

-- Wire modules together
db.init({host=config.get("dbHost"), port=5432})
server.init({port=config.get("port"), db=db})
server.start()

Semakan Pantas

Apakah tujuan utama corak modul local M = {} ... return M?

Imbas Kembali: Amalan Terbaik Modul

Ringkasan:

  • Sentiasa gunakan local M = {} ... return M
  • Persendirian = pemboleh ubah setempat aras fail; Awam = medan M
  • Singleton: require menyimpan tika modul dalam cache
  • Gunakan fungsi kilang untuk keadaan setiap tika
  • Bekukan modul dengan __newindex untuk mengelakkan pengubahsuaian
  • Uji dalam fail berasingan; dokumentasikan dengan komen ---
Percuma untuk bermula

Pelajari Lua dengan tutor kecerdasan buatan — percuma

Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.

Kursus
40
Pelajaran
159

Soalan Lazim

Adakah pelajaran “Corak Modul dan Amalan Terbaik” percuma?

Ya — sebanyak 3 pelajaran dalam laluan pembelajaran Lua Academy, termasuk “Corak Modul dan Amalan Terbaik”, boleh dibaca sepenuhnya secara percuma di web ini. Selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan interaktif dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Kursus Lua Academy merangkumi sejumlah 4 pelajaran.

Apakah yang akan saya pelajari dalam “Corak Modul dan Amalan Terbaik”?

Gunakan corak local M = {} dan dedahkan API awam dengan kemas. Anda berlatih Lua Academy menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.

Adakah saya memerlukan pengalaman untuk memulakan Lua Academy?

Tiada pengalaman terdahulu diperlukan. Pembelajaran Lua Academy di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 4 daripada 4.

Berapa lamakah pelajaran “Corak Modul dan Amalan Terbaik” diambil?

Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.

Bolehkah saya menulis dan menjalankan kod dalam pelajaran Lua Academy ini?

Ya. Setiap pelajaran Lua Academy menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.

Semua pelajaran dalam kursus ini

  1. Fungsi require
  2. Menulis Fail Modul
  3. package.path dan package.cpath
  4. Corak Modul dan Amalan Terbaik
← Kembali ke Lua Academy