Objektorientert programmering med JavaScript

Hva du skal skape

Er du kjent med begrepet "spaghetti kode"? Dette er en metafor du kan høre fra ikke-JavaScript-utviklere i kritikk av språket. Det er kode uten struktur. Den vil bestå av linje etter linje med uttalelser. Noen kan være innpakket i funksjoner, noen ikke i det hele tatt. Og hvis du er heldig, vil alle 9000 kodelinjer være i en fil. Denne "spaghetti" -strukturen er sannsynligvis et resultat av prosedyrisk programmering.

I prosedyreprogrammering brukes funksjoner til å utføre oppgaver. Vi trenger funksjoner, men vi trenger også et design vi kan jobbe med. Og mens spaghetti er flott til middag, er det ikke for kode. Motgift er objektorientert programmering. For å forstå objektorientert programmering, vil vi dekke å designe et program, definere klasser og lage objekter.

Utforme et program

La oss forestille deg at du har fått oppdraget å lage en søknad om en bokhandel. Bare for moro, la oss ringe vår bokhandel Amazonia. Amazonia vil ha bøker. Det vil bli anmeldelser for bøker. Og vi vil se opp bøker av forfatter. Det vil være flere funksjoner vi vil implementere i vår app, men dette er nok for nå.  

Objektorientert programmering er sentrert på å skape objekter. Så hvordan går vi om å oversette disse kravene til objekter? En teknikk er å lage en liste over substantivene fra vår beskrivelse og deretter forfine listen til de som er relevante for problemet. Vi nevnte følgende substantiv i vårt problem:

  • applikasjon
  • Bokhandel
  • bøker
  • anmeldelser
  • Forfatter

Søknad er et irrelevant substantiv, slik at det kan kasseres. Vi kan også kvitte seg med bokhandel fordi det ligner på søknaden. Hvis vi trengte å gjøre noe med flere bokhandlere, så kunne vi beholde det. Vi er igjen med bøker, anmeldelser og forfattere. (Forfattere har blitt pluralisert fordi vi vil ha flere forfattere i denne applikasjonen.)

La oss se på hvordan vi skal designe hver klasse. En klasse er en tegning for å skape objekter. Bokklassen vi lager, vil gi oss et blåkopi for å lage bokobjekter. 

Det ligner på hvordan en arkitekt bruker en tegning for å skape hus. Blåkopien viser soverommene, badene, kjøkkenet og stuen. Mange hus kan bli laget av denne planen. Men de trenger ikke alle å være de samme. Hvert hus kan tilpasses ved å endre maling, gulv eller inventar, for eksempel.

Oppgave

Skriv klassene du vil bruke for et handlekurvsprogram. Handlekurven skal kunne gjøre følgende: 

  1. Hold en liste over elementer.
  2. Legg til og fjern elementer fra handlekurven.
  3. Beregn summen av handlekurven.
  4. Få kundeinformasjon.
  5. Opprett kvittering for kjøpene.

klasser

For å designe vår bokklasse må vi vurdere hva klassen er ansvarlig for å vite og hva det er ansvarlig for å gjøre. For en bok må vi kjenne tittelen, forfatteren og ISBN. Dette er våre dataattributter. 

Noen ting klassen må kunne gjøre er å få og sette tittelen, få og sett forfatteren, og få og sett ISBN. Disse vil være klassens metoder. Her er hva vår bokklasse skal se ut som gitt våre krav:

klassebok konstruktør (tittel, forfatter, isbn) this.title = title; this.author = author; this.isbn = isbn;  getTitle () return this.title;  setTitle (newTitle) this.title = newTitle;  getAuthor () return this.author;  setAuthor (newAuthor) this.author = newAuthor;  getIsbn () return this.isbn;  setIsbn (newIsbn) this.isbn = newIsbn;  

Ved konvensjon er klassenavnet kapitalisert. Konstruktøren er en spesialfunksjon som deklarerer og initialiserer dataattributtene. Inne i konstruktørfunksjonen blir attributter lagt til ved hjelp av dette søkeord. Deretter er noen metoder i klassen oppført uten noen separatorer.  

Metoder som begynner med er kjent som accessor metoder fordi de returnerer en verdi. Metoder som begynner med sett er mutatormetoder fordi de lagrer en verdi eller endrer verdien av et attributt.  

Dette er den generelle formen for å definere en klasse:

klasse Klassenavn constructor (... args) this.attr = arg1; this.attr2 = arg2; ... methodOne () ... methodTwo () ...

En klasse kan også deklareres ved hjelp av denne syntaksen:

const ClassName = klasse ...

Klasser kan også ha statiske metoder. En statisk metode er en metode som tilhører klassen, ikke objektet. La oss si at vi vil lage en statisk metode for vår bokklasse for å generere ids. Dette er syntaksen:

klassebok constructor () ... static generateId () ... 

Å ringe metoden:

Book.generateId ();

Et naturlig spørsmål ville være når og hvorfor ville du bruke en statisk metode? Jeg kan ikke si at jeg vet en god grunn til å bruke statiske metoder. Det avhenger av hvordan du designer klassen din. En statisk metode kan brukes som en hjelpemetode for objektene dine, men da kan slike funksjoner lagres i sin egen klasse. Hvis du vet en god brukstilstand, la tankene dine stå i kommentarene.

Til slutt, for organisasjon, bør du lagre en klasse som en modul. En modul er bare en fil som inneholder koden din. For å gjøre vår bokklasse til en modul, legger vi til en eksport uttalelse før det.

eksport klasse bok ...

For å bruke bokstaven i en annen fil, importerer vi den.

importer bok fra boken

Hvor i inneholder verdiene som ble eksportert fra modulen, og fra boken er en referanse til filen Book.js.

Oppgave

Definer en klasse for forfattere og omtaler.  

objekter

Klassen av seg selv er ubrukelig for oss, med mindre vi gjør noe med det. Vi ønsker å lage bøker. For å gjøre det, må vi ordne klassen. Instantiate er det tekniske begrepet for å lage nye objekter. Vi kaller objektet som er opprettet fra klassen en forekomst. Slik oppretter vi en ny forekomst av en bok:

la boken = ny bok ("store forventninger", "Charles Dickens", 1234); book.getTitle () // Great Expectations

Objekter må være instantiated med ny operatør. Dataene som sendes inn i objektet, er parametrene vi definerte i vår konstruktør. Dette er den generelle formen for instantiating en klasse:

variableName = nytt ClassName (... args);

Anta at vi vil legge til attributter til vår bokklasse som en ID, pris og nummer på lager. Vi har nå seks parametre i vår konstruktør, og det er ikke pent. Det er ikke bare ille å se på. Det skaper ekstra innsats for utviklere som bruker klassen fordi de må vite rekkefølgen av argumentene. En bedre løsning er å sende et objekt som et argument. Eksempel:

klassebok constructor (data) this.id = data.id; this.title = data.title; this.author = data.author; this.isbn = data.isbn; this.units = data.units; this.price = data.price;  getTitle () return this.title;  ...

For å instantiere objektet:

la data = id: 1, tittel: "Great Expectations", forfatter: "Charles Dickens", isbn: 1234, enheter: 10, pris: 29,95 la bok = ny bok (data);

I vårt eksempel kunne vi også få tilgang til tittelen med erklæringen boktittel fordi alle egenskapene i klassen er offentlige. Nå kan du lure på hvorfor jeg opprettet alle disse metodene hvis vi kan få tilgang til attributter direkte. Var det bare å vise deg syntaksen? Ja. Også, jeg vil vise fordelene med å organisere koden din på denne måten. 

Bundling-relatert kode til et objekt kalles innkapsling. En av fordelene ved innkapsling er datagulv. Data skjuling betyr at en objekts attributter ikke kan nås utenfor klassen. 

På andre språk som Java og Python kan vi ha private attributter og private metoder. Fordi alle våre data er standard som standard i en JavaScript-klasse, kan vi ikke dra nytte av denne funksjonen. Likevel bør vi få tilgang til dataene våre med getters og settere. En konvensjon er å prefikse et attributt med et understreke _ å signalisere at det er privat.

Oppgave

Opprett et bokobjekt som bruker et forfatterobjekt for å angi forfatterattributtet.  

Siste tanker

Vi har lært at en klasse er en tegning for å skape objekter, og et objekt er en forekomst av en klasse. Fordelen med å bygge programvare inn i objekter er at den gir en programstruktur og gjør den mer overskuelig. 

Når vi har et stort program, kan delene utvikles og vedlikeholdes uavhengig av andre deler. Med denne modulariteten kommer gjenbruk. Fordi koden er innkapslet, kan objektene brukes igjen og igjen i andre deler av programmet. I tillegg har vi en kodenhet som kan testes. Jo bedre testet vår kode er, desto sikrere er det fra feil.  

Videre lesning

  • Mozilla Developer Network - Klasser
  • Du vet ikke JS: ES6 & Beyond: Kapittel 3 Organisasjon
  • Utforske ES6: Klasser