Factory-Funktionen
Teil des Abschnitts Object Oriented Programming der Lua-Journey von Coddy — Lektion 62 von 70.
Im Verlauf dieses Kurses haben Sie Objekte erstellt, indem Sie Konstruktoren direkt aufgerufen haben – Circle:new(), Rectangle:new() und so weiter. Aber was ist, wenn Sie verschiedene Arten von Objekten basierend auf einer Bedingung erstellen möchten, ohne dass der aufrufende Code wissen muss, welche spezifische Klasse verwendet werden soll?
Hier kommt das Factory-Pattern ins Spiel. Eine Factory ist einfach eine Funktion, die Objekte erstellt und zurückgibt. Der entscheidende Vorteil ist, dass der Aufrufer die Details der Objekterstellung nicht kennen muss – er fragt die Factory einfach nach dem, was er benötigt.
local function createShape(shapeType)
if shapeType == "circle" then
return Circle:new(10)
elseif shapeType == "square" then
return Square:new(5)
end
end
-- Der Aufrufer muss nichts über die Klassen Circle oder Square wissen
local myShape = createShape("circle")
print(myShape:area())
Die Factory-Funktion nimmt ein String-Argument entgegen und entscheidet, welche Klasse instanziiert werden soll. Dies zentralisiert die Logik zur Objekterstellung an einem Ort. Wenn Sie später einen neuen Formtyp hinzufügen, ändern Sie nur die Factory – nicht jedes Codestück, das Formen erstellt.
Factories sind besonders nützlich, wenn die Objekterstellung eine komplexe Einrichtung erfordert, wenn Sie Implementierungsdetails verbergen möchten oder wenn der genaue Typ des Objekts von Laufzeitbedingungen wie Benutzereingaben oder Konfigurationsdateien abhängt.
Aufgabe
EinfachLass uns eine Haustier-Fabrik (Pet Factory) bauen! Anstatt Haustiere direkt durch Aufrufen des Konstruktors jeder Klasse zu erstellen, wirst du eine Factory-Funktion erstellen, die den richtigen Haustiertyp basierend auf einem einfachen String-Argument erzeugt.
Du wirst deinen Code über vier Dateien organisieren:
Dog.lua: Erstelle eine Dog-Klasse mit einem:new(name)-Konstruktor, der den Namen des Haustiers speichert. Füge eine:speak()-Methode hinzu, die den String"{name} says: Woof!"zurückgibt (wobei {name} der Name des Hundes ist).Cat.lua: Erstelle eine Cat-Klasse mit derselben Struktur – einem:new(name)-Konstruktor und einer:speak()-Methode, die"{name} says: Meow!"zurückgibt.PetFactory.lua: Hier glänzt das Factory-Muster! Erstelle einecreatePet(petType, name)-Funktion, die zwei Argumente entgegennimmt: einen String, der den Haustiertyp angibt ("dog"oder"cat"), und den Namen des Haustiers. Die Funktion sollte das entsprechende Haustier-Objekt zurückgeben. Wenn der Typ"dog"ist, gib einen neuen Dog zurück; wenn er"cat"ist, gib eine neue Cat zurück.main.lua: Binde dein PetFactory-Modul ein. Lies zwei Eingaben ein: den Haustiertyp und den Namen des Haustiers. Verwende deine Factory-Funktion, um das Haustier zu erstellen, rufe dann dessen:speak()-Methode auf und gib das Ergebnis aus.
Das Schöne am Factory-Muster ist, dass dein Hauptcode Dog oder Cat nicht direkt einbinden muss – er kennt nur die Factory. Die Factory kümmert sich um alle Details, welche Klasse instanziiert werden soll.
Du wirst zwei Eingaben erhalten:
- Haustiertyp (entweder
"dog"oder"cat") - Haustiername (ein String)
Wenn die Eingaben beispielsweise dog und Buddy sind, sollte die Ausgabe wie folgt aussehen:
Buddy says: Woof!Wenn die Eingaben cat und Whiskers sind, sollte die Ausgabe wie folgt aussehen:
Whiskers says: Meow!Spickzettel
Das Factory-Pattern (oder Fabrikmuster) ist ein Entwurfsmuster, bei dem eine Funktion Objekte basierend auf übergebenen Parametern erstellt und zurückgibt. Der Aufrufer muss nicht wissen, welche spezifische Klasse instanziiert wird – die Factory übernimmt diese Entscheidung.
Eine Factory-Funktion zentralisiert die Logik zur Objekterstellung:
local function createShape(shapeType)
if shapeType == "circle" then
return Circle:new(10)
elseif shapeType == "square" then
return Square:new(5)
end
end
local myShape = createShape("circle")
print(myShape:area())
Vorteile des Factory-Patterns:
- Verbirgt Implementierungsdetails vor dem Aufrufer
- Zentralisiert die Objekterstellung an einem Ort
- Erleichtert das Hinzufügen neuer Typen – nur die Factory muss angepasst werden
- Nützlich, wenn der Objekttyp von Laufzeitbedingungen abhängt (Benutzereingaben, Konfiguration usw.)
- Hilfreich, wenn die Objekterstellung eine komplexe Einrichtung erfordert
Probier es selbst
-- main.lua
-- Verwende die PetFactory, um Haustiere zu erstellen
local PetFactory = require('PetFactory')
-- Eingaben lesen
local petType = io.read()
local petName = io.read()
-- TODO: Verwende PetFactory.createPet, um das Haustier zu erstellen
-- TODO: Rufe die :speak()-Methode des Haustiers auf und gib das Ergebnis aus
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Object Oriented Programming
1Das 'self'-Konzept
Tabellen mit FunktionenExplizites 'self'Die Doppelpunkt-SyntaxPunkt vs. DoppelpunktZusammenfassung – Beweglicher Punkt4Projekt: Digitale Bank
Projekt-SetupEinzahlungsmethode7Polymorphie & Überschreiben
Methoden überschreibenElternmethoden aufrufenDuck TypingGemeinsames InterfaceTyp prüfenRückblick - Mitarbeiterrollen10Projekt: Formen-Manager
Projekt-SetupRechteck-Klasse2Klassen-Prototyp-Muster
Das Prototyp-KonzeptVerknüpfung mit __indexDer :new()-KonstruktorAttribute initialisierenUnabhängige InstanzenZusammenfassung – Autofabrik5Operatorüberladung in OOP
Objekte addierenObjekte subtrahierenObjekte verkettenObjekte vergleichen (<, >)Rückblick – Wallet-Mathematik8Kapselung
NamenskonventionenClosures für private DatenZugriff über ClosuresSchreibgeschützte TabellenValidierungslogikZusammenfassung – Sicherer Tresor11Entwurfsmuster (Lite)
Factory-FunktionenSingleton-TabelleIterator-MusterObserver (Listener)Wiederholung – Logger-Factory3Objektzustand und -verhalten
InstanzvariablenGetter-MethodenSetter-MethodenBerechnete EigenschaftenStrings formatierenGleichheitsprüfungenZusammenfassung – Studentennote6Grundlagen der Vererbung
Das Vererbungs-SetupMethoden vererbenDen Konstruktor erweiternChild-Methoden hinzufügenGemeinsam vs. EinzigartigZusammenfassung - Formen-Hierarchie9Komposition & Mixins
Has-A-BeziehungDelegationEinfache MixinsAnwendung mehrerer MixinsMixins vs. VererbungZusammenfassung – Roboter-Montage12Abschluss-Herausforderungen
Wiederholung - InventarsystemWiederholung - BenutzerverwaltungWiederholung - Score-TrackerFinaler OOP-Check