Pērtiķu ielāpošana dinamiskās programmēšanas valodās: JavaScript piemērs

Javascript
dinamiskā programmēšana
Pērtiķu lāpīšana dinamiskās programmēšanas valodās cover image

Ievads

Šajā rakstā tiks apskatīti dinamiskās un statiskās programmēšanas valodu jēdzieni, galvenās atšķirības starp abām un katras paradigmas sniegtās priekšrocības un trūkumi. Šajā izpētē turpmāk uzmanība tiks pievērsta dinamiskām programmēšanas valodām, jo ​​īpaši vienam no svarīgākajiem modeļiem, ko tas iespējo: Monkey Patch, šis modelis tiks parādīts, izmantojot piemēru JavaScript.

Dinamiskās vs statiskās programmēšanas valodas

Terminoloģija

Lai saprastu, kas ir dinamiska vai statiska valoda, mums ir jāizprot daži galvenie termini, kas parasti tiek lietoti šajā kontekstā: Kompilēšanas laiks, Izpildlaiks un *Tila pārbaude *.

Kompilēšana un izpildes laiks ir divi termini, kas atbilst dažādiem datorprogrammas dzīves cikla posmiem, sākot ar kompilēšanas laiku.

Kompilēšanas laiks

Kompilēšanas laiks ir pirmais solis programmas dzīves ciklā. Izstrādātājs raksta kodu noteiktā programmēšanas valodā. Biežāk nekā nē, iekārta nespēj saprast kodu, kas rakstīts augsta līmeņa valodā, tāpēc tiek izmantots īpašs kompilators, lai to pārtulkotu zemāka līmeņa vidējā formātā, kas kļūst gatavs izpildei.

Izpildlaiks

Izpildlaikā parasti ir ietverti divi soļi: programmas ielāde atmiņā, piešķirot tās izpildei nepieciešamos resursus kopā ar instrukcijām, un pēc tam programmas izpilde šo instrukciju secībā.

Šī diagramma ilustrē šo procesu:

Tipa pārbaude

Tipa pārbaude ir iebūvēta funkcija gandrīz visās programmēšanas valodās. Tā ir iespēja pārbaudīt, vai konkrētajam mainīgajam piešķirtā vērtība atbilst šī mainīgā pareizajam veidam. Katrai programmēšanas valodai ir atšķirīgs veids, kā atmiņā attēlot noteikta veida vērtību. Šie dažādie attēlojumi ļauj pārbaudīt atbilstību starp vērtības veidu un mainīgā veidu, kuram mēģināt piešķirt šo vērtību.

Tagad, kad mums ir augsta līmeņa izpratne par programmas dzīves ciklu un tipa pārbaudi, mēs varam turpināt pētīt statiskās programmēšanas valodas.

Statiskās programmēšanas valodas

Statiskās programmēšanas valodas, ko dēvē arī par statiski drukātām valodām, ir valodas, kurās tiek izmantota tipa pārbaude, ko mēs minējām kompilēšanas fāzē. Tas faktiski nozīmē, ka mainīgais saglabā savu veidu no deklarācijas un tam nevar piešķirt citas vērtības, izņemot vērtības no deklarācijas veida. Statiskās programmēšanas valodas piedāvā papildu drošību, strādājot ar tipiem, bet var palēnināt izstrādes procesu noteiktos lietošanas gadījumos, kad tas kļūst par bargu ierobežojumu.

Dinamiskās programmēšanas valodas

No otras puses, dinamiskās programmēšanas valodas izpildes laikā izmanto tipa pārbaudi. Tas nozīmē, ka jebkuram mainīgajam var būt jebkura vērtība jebkurā programmas punktā. Tas var būt noderīgi, jo piedāvā izstrādātājam tādu elastības līmeni, kāds nav pieejams statiskajās valodās. Dinamiskās valodas parasti tiek izpildītas lēnāk nekā to statiskās valodas, jo tās ietver papildu darbību, lai dinamiski izdomātu katra mainīgā ierakstīšanu.

Pērtiķu ielāps

Statiskā un dinamiskā mašīnrakstīšana ir programmēšanas valodas pamatīpašība, jo, izmantojot vienu paradigmu pār otru, var izmantot virkni dažādu modeļu un prakses, kas var ievērojami uzlabot izstrādes kvalitāti un ātrumu. Tas var arī atvērt durvis daudziem ierobežojumiem un pretrakstiem, ja, pieņemot dizaina lēmumus, netiek ņemti vērā rūpīgi apsvērumi.

Jo īpaši ir zināms, ka dinamiski ievadītās programmēšanas valodas piedāvā augstāku elastības līmeni, jo tās neierobežo mainīgo ar vienu tipu. Šī elastība ir saistīta ar izmaksām par papildu atbildību izstrādātājam, ieviešot un atkļūdojot programmas, lai nodrošinātu, ka nenotiek neparedzama rīcība. Pērtiķu ielāpu raksts nāk no šīs filozofijas.

Monkey Patch attiecas uz komponenta darbības paplašināšanas/maiņas procesu izpildlaikā. Attiecīgais komponents var būt bibliotēka, klase, metode vai pat modulis. Ideja ir tāda pati: koda fragments ir izveidots, lai veiktu noteiktu uzdevumu, un pērtiķu ielāpu mērķis ir mainīt vai paplašināt šī koda fragmenta darbību, lai tas izpildītu jaunu uzdevumu, nemainot pašu kodu. .

Tas ir iespējams dinamiskajā programmēšanas valodā, jo neatkarīgi no tā, ar kāda veida komponentu mums ir darīšana, tam joprojām ir tāda pati objekta struktūra ar dažādiem atribūtiem, atribūtos var būt metodes, kuras var pārdalīt, lai panāktu jaunu uzvedību objektā. neiedziļinoties tās iekšējās būtībās un īstenošanas detaļās. Tas kļūst īpaši noderīgi trešo pušu bibliotēku un moduļu gadījumā, jo tos parasti ir grūtāk pielāgot.

Nākamajā piemērā tiks parādīts izplatīts lietošanas gadījums, kas var gūt labumu no pērtiķu ielāpu tehnikas izmantošanas. Šeit ieviešanai tika izmantots Javascript, taču tas joprojām būtu plaši piemērojams jebkurai citai dinamiskās programmēšanas valodai.

Piemērs

Ieviesiet minimālu testēšanas ietvaru, izmantojot mezgla vietējo HTTP moduli

Vienību un integrācijas testēšana var attiekties uz Monkey ielāpu lietošanas gadījumiem. Tie parasti ietver pārbaudes gadījumus, kas aptver vairāk nekā vienu pakalpojumu integrācijas testēšanai, vai API un/vai datu bāzes atkarības vienības testēšanai. Šajos divos scenārijos un, lai vispirms sasniegtu testēšanas mērķus, mēs vēlamies, lai mūsu testi būtu neatkarīgi no šiem ārējiem resursiem. Veids, kā to panākt, ir ņirgāšanās. Izsmiešanās simulē ārējo pakalpojumu uzvedību, lai pārbaudē varētu koncentrēties uz koda faktisko loģiku. Pērtiķu lāpīšana šeit var būt noderīga, jo tā var mainīt ārējo pakalpojumu metodes, aizstājot tās ar vietturu metodēm, kuras mēs saucam par “stub”. Šīs metodes atgriež gaidīto rezultātu testēšanas gadījumos, lai mēs varētu izvairīties no pieprasījumu ierosināšanas ražošanas pakalpojumiem tikai testu dēļ.

Šis piemērs ir vienkārša Monkey ielāpu ieviešana NodeJs vietējā http modulī. http modulis ir interfeiss, kas ievieš http protokola metodes NodeJ. To galvenokārt izmanto, lai izveidotu barebone http serverus un sazinātos ar ārējiem pakalpojumiem, izmantojot http protokolu.

Tālāk esošajā piemērā ir vienkāršs testēšanas gadījums, kad mēs izsaucam ārēju pakalpojumu, lai iegūtu lietotāju ID sarakstu. Tā vietā, lai izsauktu faktisko pakalpojumu, mēs labojam http iegūšanas metodi, lai tā vienkārši atgriež gaidīto rezultātu, kas ir nejaušu lietotāju ID masīvs. Tas var šķist mazsvarīgi, jo mēs tikai ienesam datus, taču, ja ieviešam citu testa gadījumu, kas ietver kāda veida datu izmaiņas, mēs varam nejauši izmainīt ražošanas datus, veicot testus.

Tādā veidā mēs varam ieviest savas funkcijas un rakstīt testus katrai funkcionalitātei, vienlaikus nodrošinot mūsu ražošanas pakalpojumu drošību.

// import the http module
let http = require("http");

// patch the get method of the http module
http.get = async function(url) {
  return {
    data: ["1234", "1235", "1236", "1236"]
  };
}

// example test suite, call new patched get method for testing
test('get array of user ids from users api', async () => {
  const res = await http.get("https://users.api.com/ids");
  const userIds = res.data;
  expect(userIds).toBeDefined();
  expect(userIds.length).toBe(4);
  expect(userIds[0]).toBe("1234");
});

Iepriekš minētais kods ir vienkāršs, mēs importējam http moduli, atkārtoti piešķiram http.get metodi ar jaunu metodi, kas tikai atgriež ID masīvu. Tagad mēs izsaucam jauno patched metodi testa gadījumā un iegūstam jauno gaidīto rezultātu.

~/SphericalTartWorker$ npm test

> nodejs@1.0.0 test
> jest

PASS  ./index.test.js
  ✓ get array of user ids from users api (25 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        0.977 s, estimated 2 s
Ran all test suites.

Bieži sastopamās nepilnības un ierobežojumi

Nav jābrīnās, ka pērtiķu lāpīšanai ir savi trūkumi un ierobežojumi. Mezglu moduļu sistēmas moduļu kontekstā globālā moduļa, piemēram, http, ielāpēšana tiek uzskatīta par darbību ar blakusefektiem, jo ​​http ir pieejams no jebkura punkta kodu bāzē un jebkura cita entītija var būt no tā atkarīga. Šīs entītijas sagaida, ka http modulis darbosies tā ierastajā darbībā, mainot vienu no http metodēm, mēs efektīvi pārtraucam visas pārējās http atkarības kodu bāzē.

Tā kā mēs strādājam dinamiski drukātā valodā, lietas var neizdoties uzreiz un drīzāk izmantotu neparedzamu darbību, kas padara atkļūdošanu par ārkārtīgi sarežģītu uzdevumu. Citos lietošanas gadījumos vienam un tam pašam atribūtam var būt divi dažādi viena un tā paša komponenta ielāpi, un tādā gadījumā mēs nevaram īsti paredzēt, kurš ielāps būs svarīgāks par otru, kā rezultātā kods būs vēl neparedzamāks.

Ir arī svarīgi pieminēt, ka pērtiķu lāpīšanai var būt nelielas atšķirības dažādās programmēšanas valodās. Tas viss ir atkarīgs no valodas dizaina un ieviešanas izvēlēm. Piemēram, programmā python ielāps neietekmēs visus gadījumus, kuros tiek izmantota ielāpu metode. Ja gadījums skaidri izsauc ielāpu metodi, tas iegūs jauno atjaunināto versiju, gluži pretēji, citas instances, kurām var būt tikai atribūti, kas norāda uz laboto metodi un kas to skaidri neizsauc, iegūs sākotnējo versiju, tas ir saistīts ar to, kā python iesiešana nodarbībās darbojas.

Secinājums

Šajā rakstā mēs izpētījām augsta līmeņa atšķirības starp statiskām un dinamiskām programmēšanas valodām, redzējām, kā dinamiskās programmēšanas valodas var gūt labumu no jaunām paradigmām un modeļiem, izmantojot šo valodu piedāvāto raksturīgo elastību. Mūsu parādītais piemērs bija saistīts ar Pērtiķu ielāpu, paņēmienu, ko izmanto, lai paplašinātu koda darbību, nemainot to no avota. Mēs redzējām gadījumu, kad šīs metodes izmantošana būtu izdevīga, kā arī tās iespējamie trūkumi. Programmatūras izstrāde ir saistīta ar kompromisiem, un, lai izmantotu pareizo problēmas risinājumu, izstrādātājam ir nepieciešami rūpīgi apsvērumi un laba izpratne par arhitektūras principiem un pamatiem.


Career Services background pattern

Karjeras pakalpojumi

Contact Section background image

Sazināsimies

Code Labs Academy © 2024 Visas tiesības paturētas.