Sunteți familiarizați cu termenul de "cod spaghete"? Aceasta este o metaforă pe care ați putea-o auzi de la dezvoltatorii non-JavaScript în critica limbii. Este un cod fără structură. Acesta va consta din rândul după rândul de declarații. Unele pot fi înfășurate în funcții, altele deloc. Și dacă ești norocos, toate cele 9.000 de linii de cod vor fi într-un fișier. Această structură "spaghetti" este probabil rezultatul programării procedurale.
În programarea procedurală, funcțiile sunt folosite pentru a efectua sarcini. Avem nevoie de funcții, dar avem nevoie și de un design cu care putem lucra. Și în timp ce spaghetele sunt grozave pentru cină, nu este vorba de cod. Antidotul este programare orientată pe obiecte. Pentru a înțelege programarea orientată pe obiecte, vom acoperi proiectarea unui program, definirea clasei și crearea obiectelor.
Să ne imaginăm că ți-a fost încredințată sarcina de a face o cerere pentru o librărie. Doar pentru distracție, să ne sunăm la librăria Amazonia. Amazonia va avea cărți. Vor exista recenzii pentru cărți. Și vom dori să căutăm cărți după autor. Vor fi mai multe caracteristici pe care le vom implementa în aplicația noastră, însă acest lucru este suficient pentru moment.
Programarea orientată pe obiecte se centrează pe crearea obiectelor. Deci, cum facem traducerea acestor cerințe în obiecte? O tehnică este de a face o listă de substantive din descrierea noastră și apoi de a rafina lista cu cele relevante pentru problema. Am menționat următoarele substantive în problema noastră:
Aplicația este un substantiv irelevant, deci poate fi aruncat. Putem de asemenea să scăpăm de librărie deoarece este similar cu aplicația. Dacă ar fi trebuit să facem ceva cu mai multe librării, atunci am putea să o păstrăm. Am rămas cu cărți, recenzii și autori. (Autori s-au pluralizat deoarece vom avea mai mulți autori în această aplicație.)
Acum, să ne uităm la modul în care vom proiecta fiecare clasă. O clasă este un model pentru crearea obiectelor. Clasa de cărți pe care o creăm ne va oferi un plan pentru crearea obiectelor de carte.
Este similar cu modul în care un arhitect utilizează un plan pentru a crea case. Planul va arăta dormitoarele, băile, bucătăria și sufrageria. Multe case pot fi făcute din acest plan. Cu toate acestea, nu trebuie să fie la fel. Fiecare casă poate fi personalizată prin schimbarea vopselei, a podelei sau a corpurilor de iluminat, de exemplu.
Scrieți clasele pe care le-ați folosi pentru un program de coș de cumpărături. Coșul de cumpărături ar trebui să poată face următoarele:
Pentru a proiecta clasa noastră de cărți, trebuie să luăm în considerare ce este responsabilitatea clasei pentru cunoașterea și ce este responsabil pentru a face. Pentru o carte, trebuie să cunoaștem titlul, autorul și ISBN-ul. Acestea sunt atributele noastre de date.
Unele lucruri pe care clasele trebuie să le poată face sunt să obțină și să stabilească titlul, să obțină și să stabilească autorul și să obțină și să stabilească codul ISBN. Acestea vor fi metodele clasei. Iată ce ar trebui să arate în clasa noastră de cărți cerințele noastre:
clasă carte constructor (titlu, autor, isbn) this.title = title; this.author = autor; 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;
Prin convenție, numele clasei este capitalizat. Constructorul este o funcție specială care declară și inițializează atributele de date. În interiorul funcției constructorului, atributele sunt adăugate folosind acest
cuvinte cheie. Apoi, toate metodele din clasă sunt listate fără separatori.
Metode care încep cu obține
sunt cunoscute sub numele de metode accessor, deoarece returnează o valoare. Metode care încep cu a stabilit
sunt metode mutator deoarece stochează o valoare sau modifică valoarea unui atribut.
Aceasta este forma generală pentru definirea unei clase:
clasă ClassName constructor (... args) this.attr = arg1; this.attr2 = arg2; ... metodaOne () ... methodTwo () ...
O clasă poate fi de asemenea declarată folosind această sintaxă:
const ClassName = clasa ...
Clasele pot avea și metode statice. O metodă statică este o metodă care este o proprietate a clasei, nu a obiectului. Să presupunem că vrem să creăm o metodă statică pentru clasa de cărți pentru a genera ID-uri. Aceasta este sintaxa:
clasa constructor ) ... statică generateId () ...
Pentru a apela metoda:
Book.generateId ();
O întrebare naturală ar fi când și de ce ați folosi o metodă statică? Nu pot spune că știu un motiv bun pentru a folosi metode statice. Depinde de modul în care proiectați clasa. O metodă statică ar putea fi utilizată ca metodă de ajutor pentru obiectele dvs., dar atunci aceste funcții ar putea fi stocate în propria lor clasă. Dacă știți un caz bun de utilizare, lăsați-vă gândurile în comentariile.
În cele din urmă, pentru organizare, ar trebui să păstrați o clasă ca modul. Un modul este doar un fișier care conține codul dvs. Pentru a transforma clasa noastră de cărți într-un modul, adăugăm un export
în fața acesteia.
clasa de export Carte ...
Pentru a folosi clasa Book într-un alt fișier, îl importăm.
import Book de la Carte
Unde conține valorile exportate din modul și
din Cartea
este o referință la fișierul Book.js.
Definiți o clasă pentru autori și recenzii.
Clasa însăși este inutilă pentru noi dacă nu facem ceva cu ea. Vrem să creăm cărți. Pentru a face acest lucru, trebuie să instanțiăm clasa. Instantiate este termenul tehnic pentru crearea de noi obiecte. Noi numim obiectul care este creat din clasă o instanță. Acesta este modul în care vom crea un nou exemplu al unei cărți:
lasa cartea = Noua Carte ("Marele Asteptari", "Charles Dickens", 1234); book.getTitle () // Expectări minunate
Obiectele trebuie să fie instanțiate cu nou
operator. Datele transmise în obiect sunt parametrii pe care i-am definit în constructorul nostru. Aceasta este forma generală pentru instanțierea unei clase:
variableName = nouClassName (... args);
Să presupunem că dorim să adăugăm atribute clasei noastre de carte ca un ID, preț și numărul în stoc. Acum avem șase parametri în constructorul nostru, și asta nu este destul. Nu este doar rău să te uiți. Ea creează un efort suplimentar pentru dezvoltatorii care folosesc clasa deoarece trebuie să cunoască ordinea argumentelor. O soluție mai bună este să treci un obiect ca argument. Exemplu:
clasa de clasă constructor (date) 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; ...
Pentru a instantiza obiectul:
da date = id: 1, titlu: "Expectations Great", autor: "Charles Dickens", isbn: 1234, unități: 10, preț: 29.95 carte = carte nouă;
În exemplul nostru, am fi putut accesa și titlul cu declarația titlul cartii
deoarece toate atributele din clasă sunt publice. Acum vă puteți întreba de ce am creat toate aceste metode dacă putem accesa atributele în mod direct. A fost doar pentru a vă arăta sintaxa? Da. De asemenea, vreau să arăt beneficiile organizării codului dvs. în acest fel.
Legarea codului asociat unui obiect este cunoscut sub numele de încapsulare. Unul dintre beneficiile încapsulării este ascunderea datelor. Ascunderea datelor înseamnă că atributele unui obiect nu pot fi accesate în afara clasei.
În alte limbi, cum ar fi Java și Python, putem avea atribute private și metode private. Deoarece toate datele noastre sunt publice în mod implicit într-o clasă JavaScript, nu putem profita de această caracteristică. Totuși, ar trebui să accesăm datele noastre cu getters și setters. O convenție este să prefixați un atribut cu o subliniere _
să semnaleze că este privată.
Creați un obiect de carte care utilizează un obiect autor pentru a seta atributul autor.
Am aflat că o clasă este un model pentru crearea obiectelor, iar un obiect este o instanță a unei clase. Beneficiul construirii de software în obiecte este acela că oferă o structură a programului și o face mai ușor de gestionat.
Când avem un program mare, spargerea acestuia în obiecte permite părților să fie dezvoltate și întreținute independent de alte părți. Cu această modularitate vine reutilizarea. Deoarece codul nostru este încapsulat, obiectele pot fi folosite din nou în alte părți ale programului. Plus avem o unitate de cod care poate fi testată. Cu cât codul nostru este cel mai bine testat, cu atât este mai sigur că este vorba de bug-uri.