0Pricing
Lua Academy · Lektion

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 M

Modul 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 M

Singleton-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 M

Modul-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 M

Unverä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 M

Module 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

  1. Die Funktion require
  2. Eine Moduldatei schreiben
  3. package.path und package.cpath
  4. Modulmuster und bewährte Verfahren
← Zurück zu Lua Academy