Implementieren von Schnittstellen in JavaScript mit Implement .js

Josh J
Josh J

Folgen Sie

7. November 2017 · 5 Minuten Lesezeit

In diesem Blogbeitrag werde ich das Konzept von Schnittstellen vorstellen und wie sie auch in dynamischen Sprachen nützlich sein können. Ich werde auch die Bibliothek implementieren.js, um das Konzept in JavaScript zu bringen und Ihnen zu zeigen, wie Sie Schnittstellen mit zusätzlichem Nutzen nutzen können.

Google definiert eine Schnittstelle als „einen Punkt, an dem zwei Systeme, Subjekte, Organisationen usw. meet and interact“, und diese Definition gilt für Schnittstellen in der Programmierung. In der Softwareentwicklung ist eine Schnittstelle eine Struktur, die bestimmte Eigenschaften für ein Objekt erzwingt — in den meisten Sprachen ist dieses Objekt eine Klasse.

Hier ist ein Beispiel für eine Schnittstelle in Java:

Im obigen Beispiel beschreibt die Car Schnittstelle eine Klasse, die über zwei Methoden ohne Rückgabetyp verfügt, die beide ein einzelnes Integer-Argument verwenden. Die Details der Implementierung jeder Funktion bleiben der Klasse überlassen, weshalb die Methoden beide keinen Körper haben. Um sicherzustellen, dass eine Klasse die Car Schnittstelle implementiert, verwenden wir das implements Schlüsselwort:

Einfach

Schnittstellen in JavaScript

Schnittstellen sind keine Sache in JavaScript, nicht wirklich sowieso. JavaScript ist eine dynamische Sprache, in der Typen so oft geändert werden, dass der Entwickler dies möglicherweise nicht einmal bemerkt hat. Aus diesem Grund argumentieren die Leute, dass dem ECMAScript-Standard, auf dem JavaScript basiert, keine Schnittstelle hinzugefügt werden muss.

JavaScript ist jedoch als Backend-Sprache in Form von Node massiv gewachsen.ja, und damit kommen unterschiedliche Anforderungen und ein anderes Publikum, das möglicherweise eine andere Meinung hat. Hinzu kommt, dass die Sprache schnell zum Front-End-Tool wird; Es ist an dem Punkt angekommen, an dem viele Entwickler die überwiegende Mehrheit ihres HTML-Codes darin schreiben werden .js-Dateien in Form von JSX.

Wenn die Sprache wächst, um mehr Rollen zu übernehmen, ist es hilfreich, sicherzustellen, dass eine unserer wichtigsten Datenstrukturen das ist, was wir erwartet haben. JavaScript kann das Schlüsselwort class haben, aber in Wahrheit ist dies nur eine instanziierte Konstruktorfunktion, und sobald sie aufgerufen wird, ist sie einfach ein Objekt. Objekte sind allgegenwärtig, daher ist es manchmal von Vorteil, sicherzustellen, dass sie einer bestimmten Form entsprechen.

Kürzlich habe ich bei der Arbeit einen Fall gefunden, in dem ein Entwickler erwartet hat, dass eine Eigenschaft, die als Teil einer API-Antwort zurückgegeben wird, true ist, aber stattdessen "true" , was einen Fehler verursacht. Ein einfacher Fehler, der auch hätte vermieden werden können, wenn wir eine Schnittstelle hätten.

Aber warte, es gibt noch mehr!

Schnittstellen, mit ein paar kleinen Modifikationen, könnten verwendet werden, um Objekte umzuformen. Stellen Sie sich vor, Sie implementieren eine „strikte“ Schnittstelle, bei der keine Eigenschaften außerhalb der Schnittstelle zulässig sind.

Jetzt haben wir also eine Schnittstelle, die uns sagt, wenn uns bestimmte Eigenschaften fehlen, aber auch, wenn wir unerwartete Eigenschaften haben oder wenn die Typen der Eigenschaften nicht unseren Erwartungen entsprechen. Dies fügt weitere Möglichkeiten hinzu, z. B. das Refactoring einer Antwort von einer API, während diese zusätzliche Sicherheitsebene zusätzlich zum Standardverhalten der Schnittstelle hinzugefügt wird. Wir könnten Schnittstellen auch in Komponententests verwenden, wenn sie Fehler auslösen.

Implementieren.js

Implementieren.js ist eine Bibliothek, die versucht, Schnittstellen zu JavaScript zu bringen. Die Idee ist einfach: Definieren Sie eine Schnittstelle, definieren Sie die Typen ihrer Eigenschaften und verwenden Sie sie, um sicherzustellen, dass ein Objekt das ist, was Sie erwarten.

Setup

Installieren Sie zuerst das Paket:

npm install implement-js

Erstellen Sie als nächstes ein .js—Datei und Import implementInterface und type:

Unsere erste Schnittstelle

Um eine Schnittstelle zu erstellen, rufen Sie einfach Interface auf und übergeben Sie einen String als Namen Ihrer Schnittstelle – es wird nicht empfohlen, aber wenn Sie den Namen weglassen, wird eine eindeutige ID generiert. Dies gibt eine Funktion zurück, die ein Objekt akzeptiert, bei dem die Eigenschaften alle type Objekte sind, ein zweites Argument kann auch mit Optionen übergeben werden, um Warnungen anzuzeigen, Fehler zu werfen, Eigenschaften zu löschen oder umzubenennen, sicherzustellen, dass nur die Eigenschaften der Schnittstelle vorhanden sind, oder um eine vorhandene Interface .

Hier ist eine Schnittstelle, die ein Auto beschreibt:

Es hat eine seats Eigenschaft, die vom Typ number sein sollte, ein typisches Array, das Objekte enthält, die selbst die Passenger Schnittstelle implementieren müssen, und es enthält eine beep Eigenschaft, die eine Funktion sein sollte. Die error und strict Optionen wurden auf true gesetzt, was bedeutet, dass Fehler ausgelöst werden, wenn eine Eigenschaft der Schnittstelle fehlt und auch wenn eine Eigenschaft nicht auf der Schnittstelle gefunden wird.

Implementieren unserer Schnittstelle

Jetzt wollen wir unsere Schnittstelle implementieren, in einem einfachen Beispiel werden wir ein Objekt mit einem Objektliteral erstellen und sehen, ob wir in der Lage sind, unsere Schnittstelle zu implementieren.

Zuerst erstellen wir ein Ford Objekt, dann werden wir versuchen, es gegen unsere Car Schnittstelle zu implementieren:

Wie wir aus dem obigen Kommentar sehen, wirft dies einen Fehler aus. Schauen wir uns unsere Car Schnittstelle an:

Wir können sehen, dass, während alle Eigenschaften vorhanden sind, der strikte Modus auch wahr ist, was bedeutet, dass die zusätzliche Eigenschaft fuelType einen Fehler verursacht. Obwohl wir eine passengers Eigenschaft haben, ist es kein Array.

Um die Schnittstelle korrekt zu implementieren, entfernen wir fuelType und ändern den Wert von passengers so, dass es sich um ein Array handelt, das Objekte enthält, die die Passenger:

„Aber JavaScript ist keine objektorientierte Sprache!“

Es ist wahr, dass Schnittstellen zwar typischerweise mit objektorientierten Sprachen assoziiert sind und JavaScript eine Multiparadigmensprache ist, die prototypische Vererbung verwendet, Schnittstellen jedoch dennoch sehr nützlich sein können.

Mit implement-js können wir beispielsweise eine API-Antwort einfach umgestalten und gleichzeitig sicherstellen, dass sie nicht von unseren Erwartungen abweicht. Hier ist ein Beispiel in Verbindung mit redux-thunk:

Zunächst definieren wir die TwitterUser Schnittstelle, die die User Schnittstelle erweitert, als Objekt mit twitterId und twitterUsername Eigenschaften. trim ist wahr, was bedeutet, dass wir alle Eigenschaften verwerfen, die nicht auf der TwitterUser Schnittstelle beschrieben sind. Da unsere API Eigenschaften in einem unfreundlichen Format zurückgibt, haben wir die Eigenschaften von twitter_username und twitter_id in Camelcase-Versionen von sich selbst umbenannt.

Als nächstes definieren wir eine asynchrone Aktion mit redux-thunk, die Aktion löst einen API-Aufruf aus und wir verwenden unsere TwitterUser Schnittstelle, um Eigenschaften zu verwerfen, die wir nicht wollen, und um sicherzustellen, dass sie die erwarteten Eigenschaften mit den richtigen Typen implementiert. Wenn Sie es vorziehen, Ihre Action creators pur(er) zu halten oder redux-thunk nicht zu verwenden, können Sie die Schnittstelle in twitterService.getUser überprüfen und das Ergebnis zurückgeben.

Hinweis: Beim Erweitern einer Schnittstelle werden Optionen nicht vererbt

Unit-Tests sind auch ein geeigneter Ort, um Schnittstellen zu verwenden:

Zusammenfassend

Wir haben gesehen, wie Schnittstellen in JavaScript nützlich sein können: Obwohl es sich um eine hochdynamische Sprache handelt, gibt uns die Überprüfung der Form eines Objekts und der Eigenschaften eines bestimmten Datentyps eine zusätzliche Sicherheitsebene, die wir sonst verpassen würden. Indem wir auf dem Konzept der Schnittstellen aufbauen und implement-js verwenden, konnten wir neben der zusätzlichen Sicherheit auch zusätzlichen Nutzen erzielen.

Posted on

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.