implementacja interfejsów w JavaScript z implementacją.js

Josh J
Josh J

Follow
Listopad 7, 2017 · 5 min czytaj

w tym wpisie na blogu przedstawię koncepcję interfejsów i jak mogą być przydatne nawet w językach dynamicznych. Skorzystam również z implementacji biblioteki.js to bring the concept to JavaScript, and show you how to get some extra utility out of interfaces.

Google definiuje interfejs jako „punkt, w którym dwa systemy, podmioty, organizacje itp. meet and interact”, a ta definicja odnosi się do interfejsów w programowaniu. W rozwoju oprogramowania interfejs jest strukturą wymuszającą określone właściwości obiektu — w większości języków obiekt ten jest klasą.

oto przykład interfejsu w Javie:

w powyższym przykładzie interfejsCar opisuje klasę, która ma dwie metody bez zwracanego typu, z których obie przyjmują pojedynczy argument integer. Szczegóły implementacji każdej funkcji pozostawia się klasie, dlatego obie metody nie mają ciała. Aby upewnić się, że klasa implementuje interfejsCar, używamy słowa kluczowego implements :

proste

Interfejsy w JavaScript

Interfejsy nie są czymś w JavaScript, nie tak naprawdę. JavaScript jest językiem dynamicznym, w którym typy są zmieniane tak często, że programista może nawet nie zdać sobie sprawy, z tego powodu ludzie twierdzą, że nie ma potrzeby dodawania interfejsu do standardu ECMAScript, na którym oparty jest JavaScript.

jednak JavaScript rozwinął się masowo jako język zaplecza w postaci węzła.js, a z tym wiążą się różne wymagania i inny tłum, który może mieć inne zdanie. Aby dodać do tego, język szybko staje się narzędziem front-end; dotarł do punktu, w którym wielu programistów napisze zdecydowaną większość swojego HTML w środku .Pliki js w postaci JSX.

w miarę jak język nabiera coraz większej roli, pomocne jest upewnienie się, że jedna z naszych najważniejszych struktur danych jest taka, jakiej oczekiwaliśmy. JavaScript może mieć słowo kluczoweclass, ale w rzeczywistości jest to po prostu niezauważona funkcja konstruktora, a raz wywołana jest po prostu obiektem. Przedmioty są wszechobecne, dlatego czasami korzystne jest upewnienie się, że pasują do określonego kształtu.

ostatnio w pracy znalazłem przypadek, w którym deweloper oczekiwał, że właściwość zwrócona jako część odpowiedzi API będzie true, ale zamiast tego otrzymał "true", powodując błąd. Łatwy błąd, którego można by uniknąć, gdybyśmy mieli interfejs.

ale czekaj, jest więcej!Interfejsy

, z kilkoma drobnymi modyfikacjami, mogą być używane do zmiany kształtu obiektów. Wyobraź sobie implementację” ścisłego ” interfejsu, w którym żadne właściwości poza interfejsem nie są dozwolone, możemy usunąć lub zmienić nazwy tych właściwości, a nawet wyrzucić błąd, jeśli je napotkamy.

więc teraz mamy interfejs, który powie nam, kiedy brakuje nam pewnych właściwości, ale także, gdy mamy nieoczekiwane właściwości lub jeśli typy właściwości nie są tym, czego oczekujemy. Dodaje to inne możliwości, na przykład refaktoryzację odpowiedzi z API, dodając dodatkową warstwę bezpieczeństwa na szczycie standardowego zachowania interfejsu. Możemy również użyć interfejsów w testach jednostkowych, jeśli mamy je wyrzucać błędy.

js

js jest biblioteką, która próbuje wprowadzić interfejsy do JavaScript. Pomysł jest prosty: zdefiniuj interfejs, określ typy jego właściwości i użyj go, aby upewnić się, że obiekt jest tym, czego oczekujesz.

Konfiguracja

najpierw zainstaluj pakiet:

npm install implement-js

następnie utwórz .plik js i import implementInterface I type:

nasz pierwszy interfejs

aby utworzyć interfejs, po prostu zadzwoń do Interface I podaj ciąg znaków jako nazwę interfejsu — nie jest to zalecane, ale jeśli pominiesz nazwę, wygenerowany zostanie unikalny identyfikator. Zwraca to funkcję, która akceptuje obiekt, w którym wszystkie właściwości są obiektami type, drugi argument może być również przekazany z opcjami wyświetlania ostrzeżeń, wyrzucania błędów, usuwania lub zmiany nazwy właściwości, upewnienia się, że tylko właściwości interfejsu są obecne, lub rozszerzenia istniejącego Interface.

oto interfejs opisujący samochód:

ma seats właściwość, która powinna być typu number, tablica pasażerów, która zawiera obiekty, które same muszą implementować interfejs Passenger I zawiera seatsbeep właściwość, która powinna być funkcją. Opcje error I strict zostały ustawione na true, co oznacza, że błędy będą generowane, gdy nie ma właściwości interfejsu, a także gdy właściwość nie znajduje się w interfejsie.

implementacja naszego interfejsu

teraz chcemy zaimplementować nasz interfejs, w prostym przykładzie stworzymy obiekt używając dosłownego obiektu i zobaczymy, czy jesteśmy w stanie zaimplementować nasz interfejs.

najpierw tworzymyFord obiekt, następnie spróbujemy zaimplementować go w naszymCar interfejs:

jak widzimy z powyższy komentarz powoduje błąd. Spójrzmy wstecz na naszCar interfejs:

widzimy, że podczas gdy wszystkie właściwości są obecne, tryb ścisły jest również prawdziwy, co oznacza, że dodatkowa właściwośćfuelType powoduje wyświetlenie błędu. Dodatkowo, mimo że posiadamy właściwośćpassengers, nie jest to tablica.

aby poprawnie zaimplementować interfejs, usuwamy fuelTypeI zmieniamy wartość passengerstak, że jest to tablica zawierająca obiekty implementujące interfejs Passenger :

„ale JavaScript nie jest językiem obiektowym!”

prawdą jest, że podczas gdy interfejsy są zwykle kojarzone z językami obiektowymi, a JavaScript jest językiem wieloparadygmatycznym, który wykorzystuje prototypowe dziedziczenie, interfejsy nadal mogą być bardzo przydatne.

na przykład, używając implement-js możemy łatwo refaktorować odpowiedź API, zapewniając jednocześnie, że nie odbiegała od tego, czego oczekujemy. Oto przykład używany w połączeniu z redux-thunk:

najpierw definiujemy interfejs TwitterUser, który rozszerza interfejs User, jako obiekt o twitterId I twitterUsername właściwości. trim jest prawdziwe, co oznacza, że odrzucimy wszelkie właściwości nie opisane w interfejsie TwitterUser. Ponieważ nasze API zwraca właściwości w nieprzyjaznym formacie, zmieniliśmy nazwę właściwości z twitter_username I twitter_id na same wersje camelcase.

następnie definiujemy akcję asynchroniczną za pomocąredux-thunk, akcja wyzwala wywołanie API i używamy naszego interfejsuTwitterUser, aby odrzucić właściwości, których nie chcemy i zapewnić, że implementuje właściwości, których oczekujemy, z poprawnymi typami. Jeśli wolisz zachować czystość swoich twórców akcji lub nie używaj redux-thunk, możesz sprawdzić interfejs wewnątrz twitterService.getUser I zwrócić wynik.

Uwaga: podczas rozszerzania opcji interfejsu nie są dziedziczone

testy jednostkowe są również odpowiednim miejscem do korzystania z interfejsów:

w podsumowaniu

widzieliśmy, jak interfejsy mogą być przydatne w JavaScript: mimo że jest to język bardzo dynamiczny, sprawdzenie kształtu obiektu i jego właściwości są specyficznym typem danych daje nam dodatkową warstwę bezpieczeństwa, której w przeciwnym razie byśmy nie zauważyli. Opierając się na koncepcji interfejsów i używając implement-js, udało nam się również uzyskać dodatkowe narzędzie oprócz dodatkowego bezpieczeństwa.

Posted on

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.