Bibliothek decko als Lösung für typische Programmierprobleme

Node.js-Module: decko im Fokus
Keine Kommentare

Zu den Eigenheiten von JavaScript gehört das Entstehen von Duplikaten, die Entwickler vor Herausforderungen stellen. Eine Lösung des Problems kann die Bibliothek decko mit ihrer implementierten Sammlung an Dekoratoren sein, die beispielsweise Klassen und Methoden um wichtige Eigenschaften zur problemlosen Programmierung ergänzt.

Fragt man einen Entwickler, was guten Code ausmacht, so antworten viele, dass guter Code möglichst wenige Duplikate aufweisen sollte. Viele dieser Duplikate entstehen durch Eigenheiten von JavaScript selbst. Der Vorteil ist, dass Sie mit Ihren Problemen glücklicherweise nicht alleine sind. Stoßen Sie auf Schwierigkeiten, sollte Ihre erste Anlaufstelle die npm-Plattform sein. In den meisten Fällen werden Sie hier schnell fündig, wenn es um kreative Lösungen geht. Ein Beispiel für eine solche Lösung von typischen Programmierproblemen ist die Bibliothek decko. Hierbei handelt es sich um eine Sammlung von drei Dekoratoren:

  • @bind: Mit diesem Dekorator wird der Wert von this einer Methode fest gebunden.
  • @debounce: Dieser Dekorator sorgt dafür, dass eine Methode nicht zu oft aufgerufen wird.
  • @memoize: Dieser Dekorator bietet Ihnen die Möglichkeit, Rückgabewerte von Funktionen zu cachen.

Was sind Dekoratoren?

Dekoratoren sind ein Feature, das zukünftig in den JavaScript-Standard aufgenommen werden soll. Aktuell werden Dekoratoren noch von keinem Browser unterstützt. Mit einem Transpiler wie beispielsweise TypeScript können Sie dieses Feature bereits jetzt in Ihrer Applikation nutzen. Populäre Beispiele für die Verwendung von Dekoratoren sind clientseitig Angular und serverseitig Nest.js. Beide Lösungen setzen dieses Feature häufig ein, um Klassen, Methoden oder Eigenschaften durch zusätzliche Informationen zu ergänzen. Ein Dekorator steht dabei immer bei der Struktur, auf die er zugreifen soll, und wird mit dem @-Zeichen eingeleitet. Im Kern ist ein Dekorator nichts weiter als eine Funktion, die mit der jeweiligen Struktur, also beispielsweise der Methode, aufgerufen wird. Listing 1 zeigt ein einfaches Beispiel für einen Dekorator.

function myDecorator(target: User) {
  console.log(target);
}

@myDecorator
class User {}

const klaus = new User();

Der Dekorator in Listing 1 gibt lediglich eine Repräsentation der Klasse auf der Konsole aus. Im Zuge der Funktion haben Sie jedoch auch die Möglichkeit, schreibend auf die Struktur der Klasse zuzugreifen. Ein weiteres Feature, das Sie mit Dekoratoren umsetzen können, ist ein konfigurierbarer Dekorator. In diesem Fall ist die Dekoratorfunktion eine Art Factory, die die eigentliche Dekoratorfunktion zurückgibt und ihrerseits zusätzliche Argumente entgegennimmt, um den Dekorator zu konfigurieren. Hier geben Sie den Dekorator nicht einfach an, sondern nutzen ihn wie eine Funktion.

International PHP Conference

Entwickler – das verlorene Handbuch

by Stefan Priebsch (thePHP.cc)

My browser does what?

by Joel Lord (Red Hat OpenShift

JavaScript Days 2019

Einführung in Node.js

mit Golo Roden (the native web)

Concepts of the modern Web

mit Sven Kölpin (OPEN KNOWLEDGE)

Damit Sie Dekoratoren in TypeScript ohne Warnung nutzen können, müssen Sie sie über ein Flag aktivieren. Dies geschieht entweder über die Kommandozeile beim Aufruf des TypeScript-Compilers mit der Option —experimentalDecorators oder in der tsconfig.json-Datei über den Schlüssel experimentalDecorators.

Auf dieser technischen Basis bauen die Dekoratoren von decko auf.

Der „@bind“-Dekorator

Mit dem @bind-Dekorator lässt sich ein recht häufig anzutreffendes Problem lösen. Nutzen Sie eine Methode einer Klasse als Callback-Funktion beispielsweise in einem setTimeout, verlieren Sie den Bezug zum Objekt, an das die Methode gebunden ist. Listing 2 zeigt ein einfaches Beispiel hierfür.

class DeckoTest {
  private name = 'Klaus';

  cb() {
    console.log(this.name);
  }
}

const d = new DeckoTest();

setTimeout(d.cb, 1000);

Anders als in diesem Beispiel zu erwarten wäre, ist die Ausgabe auf der Konsole, wenn Sie den Quellcode beispielsweise mit ts-node auf der Kommandozeile ausführen, nicht die Zeichenkette „Klaus“, sondern „undefined“. Zur Lösung dieses Problems gibt es mehrere Ansätze. So können Sie die cb-Methode beispielsweise mit der bind-Methode in den gewünschten Kontext binden oder Sie definieren die cb-Methode als Eigenschaft der Klasse und weisen ihr als Wert eine Arrow-Funktion zu. Alle diese Varianten sind wenig elegant und an genau diesem Punkt setzt der @bind-Dekorator von decko an. In Listing 3 sehen Sie die Lösung mit diesem.

import { bind } from 'decko';

class DeckoTest {
  private name = 'Klaus';

  @bind
  cb() {
    console.log(this.name);
  }
}

const d = new DeckoTest();

setTimeout(d.cb, 1000);

Führen Sie diesen Quellcode erneut aus, ist die Ausgabe dann „Klaus“. Auf solche Problemstellungen stoßen Sie in clientseitigem JavaScript beispielsweise recht häufig, wenn Sie mit React entwickeln und Event Handler implementieren.

Der „@debounce“-Dekorator

Der @debounce-Dekorator sorgt dafür, dass eine Methode maximal einmal in einem bestimmten Zeitraum ausgeführt wird. Dieser Dekorator eignet sich besonders für den Einsatz in Event Handlern, bei denen eine zu häufige Ausführung wenig Sinn macht. Die Funktion wird stets mit dem aktuellsten Aufruf ausgeführt. In Listing 4 sehen Sie ein Beispiel für den @debounce-Operator.

import { debounce } from 'decko';

class DeckoTest {
  @debounce(1000)
  cb() {
    console.log('Hello');
  }
}

const d = new DeckoTest();

let count = 0;

const i = setInterval(() => {
  if (count++ >= 11) {
    clearInterval(i);
  }
  d.cb();
}, 100);

Wie Sie im Codebeispiel sehen können, wird dem @debounce-Dekorator eine Zahl übergeben. Diese gibt die Anzahl an Millisekunden an, die der Dekorator aktiv sein soll. Der Code im Beispiel führt dazu, dass Sie bei seiner Ausführung insgesamt zwei Ausgaben auf der Konsole erhalten und nicht zwölf, wie ohne den Dekorator.

Der „@memoize“-Dekorator

Mit dem @memoize-Dekorator können Sie einen einfachen Cache für Methoden implementieren. Dieser spielt seine Stärke vor allem bei ressourcenintensiven Routinen aus. Der Cache ordnet die Einträge den Argumenten zu, die der Methode übergeben wurden. Das bedeutet, dass eine Voraussetzung für die Verwendung dieses Dekorators ist, dass eine Kombination aus Argumenten immer dasselbe Ergebnis liefert. Die Argumente werden zur Überprüfung in Zeichenketten konvertiert.

Der @memoize-Dekorator ist als Dekorator-Factory umgesetzt. Das bedeutet, dass Sie ihm ein Objekt zur Konfiguration übergeben können. Dieses Objekt kann über zwei Eigenschaften verfügen: caseSensitive und cache. Der caseSensitive-Eigenschaft können Sie den Wert false übergeben. Dann wird die Groß- und Kleinschreibung bei den Cacheschlüsseln ignoriert. Die cache-Eigenschaft erwartet ein Objekt, das zur Vorbefüllung des Cache verwendet werden kann. In Listing 5 finden Sie ein Beispiel für den Einsatz dieses Dekorators.

import { memoize } from 'decko';

class DeckoTest {
  @memoize()
  cb(name: string) {
    console.log(name);
    return name;
  }
}

const d = new DeckoTest();

d.cb('Klaus');
d.cb('Klaus');

Führen Sie den Quellcode aus, erhalten Sie eine Ausgabe auf der Konsole. Beim zweiten Aufruf der cb-Methode wird der Quellcode nicht mehr ausgeführt, sondern der Rückgabewert direkt aus dem Cache ermittelt.

Fazit

Bei decko handelt es sich um eine überschaubare Bibliothek, die im Kern lediglich aus knapp über hundert Zeilen Quellcode besteht. In der täglichen Arbeit lösen die drei Dekoratoren jedoch recht häufig auftretende Probleme, die sich ansonsten nur mit Eigenimplementierungen lösen lassen, die den Quellcode einer Applikation nicht lesbarer werden lassen.

PHP Magazin

Entwickler MagazinDieser Artikel ist im PHP Magazin erschienen. Das PHP Magazin deckt ein breites Spektrum an Themen ab, die für die erfolgreiche Webentwicklung unerlässlich sind.

Natürlich können Sie das PHP Magazin über den entwickler.kiosk auch digital im Browser oder auf Ihren Android- und iOS-Devices lesen. In unserem Shop ist das Entwickler Magazin ferner im Abonnement oder als Einzelheft erhältlich.

Unsere Redaktion empfiehlt:

Relevante Beiträge

Hinterlasse einen Kommentar

Hinterlasse den ersten Kommentar!

avatar
400
  Subscribe  
Benachrichtige mich zu:
X
- Gib Deinen Standort ein -
- or -