implementering af grænseflader i JavaScript med implementering.js

Josh J

Følg
Nov 7, 2017 · 5 min læs

i dette blogindlæg vil jeg introducere begrebet grænseflader og hvordan de kan være nyttige selv på dynamiske sprog. Jeg vil også bruge biblioteket implementere.js for at bringe konceptet til JavaScript, og vise dig, hvordan du får noget ekstra værktøj ud af grænseflader.

Google definerer en grænseflade som ” et punkt, hvor to systemer, emner, organisationer osv. Mød og interagere, ” og denne definition gælder for grænseflader i programmering. En grænseflade er en struktur, der håndhæver specifikke egenskaber på et objekt — på de fleste sprog er dette objekt en klasse.

Her er et eksempel på en grænseflade i Java:

i ovenstående eksempel beskriverCar interface en klasse, der har to metoder uden returtype, som begge tager et enkelt heltalsargument. Detaljerne om implementeringen af hver funktion overlades til klassen, derfor har metoderne begge ingen krop. For at sikre, at en klasse implementerer Car interface, bruger vi implements søgeord:

Simple

grænseflader i JavaScript

grænseflader er ikke noget i JavaScript, ikke rigtig alligevel. JavaScript er et dynamisk sprog, hvor typer ændres så ofte, at udvikleren måske ikke engang har indset, på grund af dette hævder folk, at der ikke er behov for en grænseflade, der skal føjes til ECMAScript-standarden, som JavaScript er baseret på.

JavaScript er dog vokset massivt som et backend-sprog i form af Node.js, og med det kommer forskellige krav og en anden skare, der kan have en anden mening. For at tilføje til dette bliver sproget hurtigt front-end-værktøjet; det er kommet til det punkt, hvor mange udviklere vil skrive langt størstedelen af deres HTML inde .JS filer i form af JS.

så som sproget vokser til at påtage sig flere roller, er det nyttigt at sikre, at en af vores mest afgørende datastrukturer er, hvad vi forventede at være. JavaScript kan haveclass søgeordet, men i sandhed er dette bare en afinstalleret konstruktørfunktion, og en gang kaldet er det simpelthen et objekt. Objekter er allestedsnærværende, så det er undertiden fordelagtigt at sikre, at de matcher en bestemt form.

for nylig på arbejde fandt jeg en sag, hvor en udvikler forventede, at en ejendom, der blev returneret som en del af et API-svar, skulle være truemen i stedet fik "true", der forårsager en fejl. En let fejl, og en, der også kunne have været undgået, hvis vi havde en grænseflade.

men vent, der er mere!

grænseflader, med et par mindre ændringer, kunne bruges til at omforme objekter. Forestil dig at implementere en” streng ” grænseflade, hvor ingen egenskaber uden for grænsefladen er tilladt, vi kunne slette eller omdøbe disse egenskaber eller endda smide en fejl, hvis vi støder på dem.

så nu har vi en grænseflade, der fortæller os, hvornår vi mangler visse egenskaber, men også når vi har uventede egenskaber, eller hvis egenskabernes typer ikke er, hvad vi forventer. Dette tilføjer andre muligheder, for eksempel refactoring et svar fra en API, mens du tilføjer det ekstra lag af sikkerhed oven på grænsefladens standardadfærd. Vi kunne også bruge grænseflader i enhedstest, hvis vi får dem til at kaste fejl.

implementere.JS

implementere.js er et bibliotek, der forsøger at bringe grænseflader til JavaScript. Ideen er enkel: Definer en grænseflade, Definer typerne af dens egenskaber, og brug den til at sikre, at et objekt er, hvad du forventer, at det skal være.

opsætning

Installer først pakken:

npm install implement-js

Opret derefter en .js file and import implementInterface og type:

vores første grænseflade

for at oprette en grænseflade skal du blot ringe Interface og videregive en streng som navnet på din grænseflade — det anbefales ikke, men hvis du udelader navnet, genereres et unikt id. Dette returnerer en funktion, der accepterer et objekt, hvor egenskaberne alle er type objekter, et andet argument kan også sendes med muligheder for at vise advarsler, kaste fejl, slette eller omdøbe egenskaber, sikre, at kun egenskaberne for grænsefladen er til stede, eller for at udvide et eksisterende Interface.

Her er en grænseflade, der beskriver en bil:

det har en seats ejendom, der skal være af type Nummer, et passagerarray, der indeholder objekter, der selv skal implementere Passenger interface, og det indeholder en Passenger interface, og det indeholder en Passengerbeep

ejendom, som skal være en funktion. error ogstrict indstillingerne er indstillet til true, hvilket betyder, at fejl vil blive kastet, når en egenskab af grænsefladen mangler, og også når en egenskab, der ikke findes på grænsefladen, findes.

implementering af vores interface

nu vil vi implementere vores interface, i et simpelt eksempel opretter vi et objekt ved hjælp af et objekt bogstaveligt og se, om vi er i stand til at implementere vores interface.

først opretter vi et Ford objekt, så vil vi forsøge at implementere det mod vores Car interface:

som vi ser fra kommentaren ovenfor, dette kaster en fejl. Lad os se tilbage på voresCar interface:

Vi kan se, at mens alle egenskaber er til stede, er streng tilstand også sand, hvilket betyder, at den ekstra egenskabfuelType forårsager en fejl, der skal kastes. Selvom vi har enpassengers ejendom, er det ikke et array.

for at implementere grænsefladen korrekt fjerner vi fuelType og ændrer værdien af passengers så det er et array, der indeholder objekter, der implementerer Passenger interface:

” men JavaScript er ikke et objektorienteret sprog!”

det er rigtigt, at selvom grænseflader typisk er forbundet med objektorienterede sprog, og JavaScript er et multiparadigmesprog, der bruger prototypisk arv, kan grænseflader stadig være meget nyttige.

for eksempel ved hjælp afimplement-js kan vi nemt refactorere et API-svar, samtidig med at det sikres, at det ikke afviger fra det, vi forventer. Her er et eksempel brugt sammen med redux-thunk:

først definerer vi TwitterUser interface, som udvider User interface, som et objekt med twitterId og twitterUsername egenskaber. trim er sandt, hvilket betyder, at vi vil kassere alle egenskaber, der ikke er beskrevet på TwitterUser interface. Da vores API returnerer egenskaber i et uvenligt format, har vi omdøbt egenskaberne fra twitter_username og twitter_id til camelcase-versioner af sig selv.

dernæst definerer vi en async-handling med redux-thunk, handlingen udløser et API-opkald, og vi bruger vores TwitterUser interface til at kassere egenskaber, vi ikke ønsker, og for at sikre, at den implementerer de egenskaber, vi forventer, med de korrekte typer. Hvis du foretrækker at holde dine actionskabere rene (er) eller ikke bruger redux-thunk, kan du kontrollere grænsefladen inde i twitterService.getUser og returnere resultatet.

Bemærk: Når du udvider en grænseflade, er indstillingerne ikke arvet

enhedstest er også et passende sted at bruge grænseflader:

Sammenfattende

Vi har set, hvordan grænseflader kan være nyttige i JavaScript: selvom det er et meget dynamisk sprog, kontrollerer formen på et objekt, og at dets egenskaber er en bestemt datatype, giver os et ekstra lag af sikkerhed, som vi ellers ville gå glip af. Ved at bygge videre på begrebet grænseflader og bruge implement-js vi har også været i stand til at få yderligere nytte oven på den ekstra sikkerhed.

Posted on

Skriv et svar

Din e-mailadresse vil ikke blive publiceret.