JavaScript-Entwurfsmuster Teil 1: Das Fabrikmuster

Da die Projekte, an denen ich arbeiten durfte, in letzter Zeit gewachsen sind, habe ich mir die Zeit genommen, tiefer in Designmuster einzutauchen, um besser wartbaren und skalierbaren Javascript-Code zu schreiben. Entwurfsmuster sind eine großartige Möglichkeit, zeit- und kampferprobte Lösungen auf häufige Probleme anzuwenden, damit wir sie schneller und effizienter lösen können.

Die meisten der von uns behandelten Entwurfsmuster basieren auf objektorientierter Programmierung, und daher ist es nur sinnvoll, dass wir uns zunächst ein so genanntes Kreationsmuster ansehen, da das Muster uns eine klare Schnittstelle zum Erstellen von Objekten bietet, während wir davon abstrahieren die unterschiedliche Komplexität oder Logik, die mit ihrer Erstellung verbunden ist. Dieses Muster wird als Fabrikmuster bezeichnet und ermöglicht es uns, auf einfache Weise Objekte in JavaScript zu erstellen.

Wenn man von anderen klassenbasierten OOP-Sprachen kommt, könnte man versucht sein zu glauben, dass wir in den folgenden Codezeilen Klassen und Instanzen erstellen, aber in Wirklichkeit ist dies nur syntaktischer Zucker, der wie die Syntax einer Klasse aussieht basierte Sprache.

Was wir tatsächlich tun, ist die prototypische Vererbung von JavaScript und OLOO (Objects Linking to Other Objects) zu nutzen, um Objekte mit einem gemeinsam genutzten Prototyp zu erstellen. Der Prototyp selbst ist nur ein einfaches JavaScript-Objekt und keine Klasse im eigentlichen Sinne des Wortes. Eine großartige Erklärung der Vererbung in Javascript und ihrer Unterschiede zur klassischen Vererbung finden Sie in Eric Elliots Artikel hier.
Lassen Sie uns in einen Code eintauchen.

Alle Beispiele aus dieser Reihe werden hier auf Github verfügbar sein und Anweisungen zur Ausführung des Codes enthalten.
Um den Code in diesem Artikel auszuführen, muss Node auf Ihrem Computer installiert sein. Befolgen Sie diese Anweisungen, falls Sie sie noch nicht haben. Wenn Sie dem Repo folgen, finden Sie Anweisungen zum Ausführen des Codes in der Readme-Datei.

Das Wichtigste zuerst, erstellen wir einen Ordner. Wir können es javascript-design-patterns in diesem Ordner nennen, wir werden einen Factory-Ordner erstellen.
Das Fabrikmuster in Aktion

Das Fabrikmuster umschließt einen Konstruktor für verschiedene Arten von Objekten und gibt Instanzen der Objekte über eine einfache API zurück. Es macht es einfach, verschiedene Objekte zu erstellen, indem es eine einfache API verfügbar macht, die den angegebenen Objekttyp zurückgibt.
Beginnen wir mit der Erstellung unserer Konstruktoren. Diese Funktionen sind dafür verantwortlich, neue Objekte eines bestimmten Typs zurückzugeben, wenn sie aufgerufen werden.

Lassen Sie uns im Factory-Ordner eine laptop.js-Datei erstellen.

const Laptop = function({ ram, hdd, name }) {
  this.ram = ram || 0;
  this.hdd = hdd || 0;
  this.name = name || "";
};

module.exports = Laptop;

In dieser Datei erstellen wir eine Laptop-Konstruktorfunktion. Es akzeptiert ein Objekt als Parameter mit Attributen zum Instanziieren des Objekts mit verschiedenen Spezifikationen, die wir erfassen möchten – in diesem Fall RAM-Größe, Festplattengröße und einen Gerätenamen.
Danach exportieren wir die Laptop-Konstruktorfunktion aus dem Modul.

Lassen Sie uns eine weitere Datei namens tablet.js erstellen

Wir werden dasselbe tun, aber mit Spezifikationen, die für ein Tablet relevanter sind.

const Tablet = function({ ram, hdd, name, network }) {
    this.ram = ram || 0;
    this.hdd = hdd || 0;
    this.network = network || 0;
    this.name = name || "";
};

module.exports = Tablet;

Nachdem wir nun unsere Konstruktoren haben, erstellen wir die Factory-Funktion, die die API zum Erstellen neuer Instanzen dieser Elemente verfügbar macht. Fügen Sie eine neue Datei namens gadgetFactory.js hinzu

const Laptop = require("./laptop");
const Tablet = require("./tablet");
const gadget = { Laptop, Tablet };

module.exports = {
    createGadget(type, attributes) {
        const GadgetType = gadget[type];
        return new GadgetType(attributes);
    }
};

Hier beginnen wir mit dem Importieren der Konstruktoren zum Erstellen von Laptop- und Tablet-Objekten. Dann erstellen wir ein Gadget-Objekt, indem wir die Konstruktornamen als Schlüssel verwenden. Dadurch können wir mit Gadget auf den gewünschten Konstruktortyp zugreifen[type]- wobei in diesem Beispiel der Typ entweder „Laptop“ oder „Tablet“ lautet.

Schließlich exportieren wir ein Objekt aus diesem Modul mit einer createGadget-Methode. Diese Methode akzeptiert einen Gadget-Typ als ersten Parameter und ruft den angegebenen Konstruktortyp auf, während ihm die Attribute übergeben werden.

Sie sollten beachten, dass wir beim Aufruf einer Funktion mit dem Schlüsselwort new in Javascript ein leeres Objekt zurückerhalten, bei dem eine this-Bindung auf die in der ausführenden Funktion festgelegt ist. Dieser eindeutige Aufruf erstellt auch eine prototypische Beziehung zwischen der Konstruktorfunktion und allen neuen Objekten, die wir auf diese Weise erstellen. Wir werden dies in den anderen Designmustern, die wir behandeln werden, im Detail sehen.

Bemerkenswert ist auch, dass der große Anfangsbuchstabe nur eine Konvention und keine Voraussetzung ist. Es macht nichts Besonderes und wir hätten die Funktionen genauso gut mit camelCase benennen können, wie wir es normalerweise mit anderen Variablen- und Funktionsnamen in JavaScript tun.

An diesem Punkt können wir jetzt die Datei erstellen, die unsere Factory-Pattern-API verwendet (oder verbraucht).

Erstellen Sie eine index.js-Datei und fügen Sie den folgenden Code hinzu.

const gadgetFactory = require("./gadgetFactory");
const myLaptop = gadgetFactory.createGadget("Laptop", {
    ram: 8,
    ssd: 256,
    name: "Bab's MacBook Pro"
});

const myTablet = gadgetFactory.createGadget("Tablet", {
    ram: 4,
    hdd: 128,
    name: "Bab's iPad",
    network: '4G'
});

console.log(myLaptop);
console.log(myTablet);

Als erstes werden Sie vielleicht bemerken, dass wir in dieser Datei die Konstruktoren für Laptops und Tablets nicht direkt benötigen. Alles, was wir brauchen, ist das gadgetFactory-Modul (mit seiner createGadget-Methode). Mit dieser Methode erstellen wir dann jeweils zwei Instanzen eines Laptops und eines Tablets und melden sie an der Konsole ab.

Navigieren Sie nun in Ihrem Terminal zum Ordner javascript-design-patterns und geben Sie Folgendes ein:

$ node ./factory/index.js

Sie sollten Folgendes in der Konsole protokolliert sehen:

Laptop { ram: 8, ssd: 256, name: 'Bab\'s MacBook Pro' }
Tablet { ram: 4, hdd: 128, network: '4G', name: 'Bab\'s iPad' }

Wie Sie sehen können, haben wir einen Laptop-Objekttyp sowie einen Tablet-Typ mit jeweils eigenen Spezifikationen erstellt. Mit diesem Muster können Sie beliebig viele Gadget-Objekte mit jeweils eigenen Spezifikationen erstellen.

Und das war’s für das Werksmuster. Dies ist natürlich eine ziemlich vereinfachte Implementierung, und in alles andere als eine triviale App möchten Sie auf jeden Fall eine strengere Logik einbauen – zum Beispiel in Bezug auf Ihre Konstruktoren.

In diesem Beispiel haben wir die Konstruktorfunktionen von Javascript verwendet, aber dieses Muster kann auch mithilfe von Prototypen implementiert werden.

Similar Posts

Leave a Reply

Your email address will not be published.