Modulmuster und bewährte Verfahren
Verwenden Sie das Muster local M = {} und stellen Sie eine öffentliche API übersichtlich bereit
Modulmuster und bewährte Verfahren ist eine kostenlose Lua Academy-Lektion auf CoddyKit. Dies ist Lektion 4 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Lua Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Lua Academy-Kurs umfasst insgesamt 4 Lektionen.
Das Muster M = {}
Das universelle Lua-Modulmuster: Deklarieren Sie eine lokale Tabelle, füllen Sie sie und geben Sie sie zurück. Alle öffentlichen Symbole kommen in M; alle privaten Hilfsfunktionen sind einfache lokale Variablen. Dieses Muster ist übersichtlich, minimal und funktioniert überall.
-- 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 MModul mit Selbstreferenz
Innerhalb eines Moduls können Funktionen andere Modulfunktionen entweder über ihren Namen (M.foo()) oder als lokale Variablen aufrufen. Die Verwendung lokaler Variablen ist etwas schneller; die Verwendung von M.foo() ermöglicht es Benutzern, M.foo zu überschreiben, sodass der interne Aufruf die Überschreibung verwendet (Monkey-Patching).
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 MSingleton-Muster
Ein Modul kann als Singleton dienen: Es besitzt einen veränderlichen internen Zustand, der von allen Aufrufern gemeinsam genutzt wird. Da require das Modul zwischenspeichert, erhalten alle Aufrufe von require("mod") dasselbe Objekt mit demselben Zustand.
-- 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 als Namespace
Verwenden Sie ein Modul ausschließlich als Namespace, um die globale Tabelle nicht zu verunreinigen. Gruppieren Sie zusammengehörige Konstanten und Hilfsfunktionen unter einem Namen, ähnlich wie ein Paket in anderen Sprachen.
-- 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 ...Factory-Modul
Ein Modul, das anstelle einer einfachen Tabelle eine Factory-Funktion exportiert. Die Factory erstellt und gibt neue Instanzen mit jeweils eigenem privaten Zustand zurück. Das ist das Klassenmuster auf Modulebene.
-- 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 MModul-Init-Funktion
Manche Module benötigen vor ihrer Verwendung eine Konfiguration. Stellen Sie eine Funktion M.init(config) bereit, die die Konfiguration im privaten Zustand des Moduls speichert. Das ermöglicht Dependency Injection und erleichtert das Testen.
-- 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 MUnveränderliches Modul
Verhindern Sie versehentliche Änderungen an der Modul-API, indem Sie mit __newindex alle Schreibzugriffe blockieren. Das ist besonders für Bibliotheksmodule nützlich, bei denen versehentliches Monkey-Patching zu Fehlern führen könnte.
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)Dokumentieren mit LDoc
Eine verbreitete Konvention zur Dokumentation von Lua-Modulen sind Kommentare im LDoc-Stil mit dem Präfix ---. Obwohl dies von der Sprache nicht erzwungen wird, ermöglichen diese Kommentare Dokumentationsgeneratoren, automatisch API-Dokumentation zu erstellen.
--- 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 MModule testen
Testen Sie ein Modul, indem Sie es per require laden und jede Funktion ausführen. Verwenden Sie einen einfachen Test-Runner oder busted (das Lua-Testframework). Bewahren Sie die Tests in einer separaten Datei auf, die den Pfad des Moduls nachbildet.
-- 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)Module zusammensetzen
Komplexe Systeme setzen sich aus mehreren Modulen zusammen. Ein Haupteinstiegspunkt lädt die Untermodule per require und verbindet sie miteinander. Diese Trennung der Zuständigkeiten hält jedes Modul fokussiert und unabhängig testbar.
-- 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()Kurzer Check
Was ist der Hauptzweck des Lua-Modulmusters local M = {} ... return M?
Zusammenfassung: Bewährte Modulpraktiken
Zusammenfassung:
- Verwenden Sie immer
local M = {} ... return M - Privat = lokale Variablen auf Dateiebene; öffentlich = M-Felder
- Singleton: require speichert die Modulinstanz zwischen
- Verwenden Sie Factory-Funktionen für instanzspezifischen Zustand
- Frieren Sie Module mit __newindex ein, um Änderungen zu verhindern
- Testen Sie in separaten Dateien; dokumentieren Sie mit ----Kommentaren
Häufig gestellte Fragen
Ist die Lektion „Modulmuster und bewährte Verfahren“ kostenlos?
Ja — der vollständige Text von „Modulmuster und bewährte Verfahren“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Lua Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Lua Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Modulmuster und bewährte Verfahren“?
Verwenden Sie das Muster local M = {} und stellen Sie eine öffentliche API übersichtlich bereit Du übst Lua Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um Lua Academy zu starten?
Keine Vorkenntnisse erforderlich. Lua Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 4 von 4.
Wie lange dauert die Lektion „Modulmuster und bewährte Verfahren“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser Lua Academy-Lektion Code schreiben und ausführen?
Ja. Jede Lua Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Die Funktion require
- Eine Moduldatei schreiben
- package.path und package.cpath
- Modulmuster und bewährte Verfahren