Monkey Patching in dinamiese programmeertale: 'n JavaScript-voorbeeld

Javascript
dinamiese programmering
Monkey Patching in dinamiese programmeertale cover image

Inleiding

Hierdie artikel sal die konsepte van dinamiese en statiese programmeertale ondersoek, die belangrikste verskille tussen die twee, en wat elke paradigma bied in terme van voordele en slaggate. Hierdie verkenning sal verder fokus op dinamiese programmeertale, veral een van die noodsaaklike patrone wat dit moontlik maak: Monkey Patch, hierdie patroon sal met behulp van 'n voorbeeld in JavaScript vertoon word.

Dinamiese vs statiese programmeertale

Terminologie

Om te verstaan ​​wat 'n dinamiese taal of 'n statiese taal uitmaak, moet ons 'n begrip vestig van 'n paar sleutelterme wat algemeen in hierdie konteks gebruik word: Steltyd, Loptyd en *Typekontrole *.

Compile en Runtime is twee terme wat ooreenstem met verskillende stadiums in die lewensiklus van 'n rekenaarprogram, wat begin met Compile time.

Stel tyd saam

Opsteltyd is die eerste stap in die lewensiklus van 'n program. 'n Ontwikkelaar skryf kode in 'n gegewe programmeertaal. Meer dikwels as nie, is die masjien nie in staat om die kode wat in 'n hoëvlaktaal geskryf is, te verstaan ​​nie, so 'n toegewyde samesteller word gebruik om dit te vertaal na 'n laervlak intermediêre formaat wat gereed word vir uitvoering.

Looptyd

Looptyd sluit gewoonlik twee stappe in: laai die program in die geheue deur die hulpbronne wat nodig is vir die uitvoering daarvan saam met sy instruksies toe te wys, en voer dan die program uit volgens die volgorde van daardie instruksies.

Die volgende diagram illustreer hierdie proses:

Tipekontrolering

Tipe-kontrolering is 'n ingeboude kenmerk in byna alle programmeertale. Dit is die vermoë om te kontroleer of 'n waarde wat aan 'n gegewe veranderlike toegeken is, ooreenstem met die korrekte tipe van daardie veranderlike. Elke programmeertaal het 'n ander manier om 'n waarde van 'n gegewe tipe in die geheue voor te stel. Hierdie verskillende voorstellings maak dit moontlik om die ooreenstemming tussen die tipe waarde en die tipe veranderlike waaraan jy probeer om daardie waarde toe te wys, na te gaan.

Noudat ons 'n hoëvlakbegrip van 'n programlewensiklus en tipekontrolering het, kan ons voortgaan om statiese programmeertale te verken.

Statiese programmeertale

Statiese programmeertale, ook na verwys as staties getikte tale, is tale wat die tipe kontrolering toepas wat ons tydens die samestellingsfase genoem het. Dit beteken effektief dat 'n veranderlike sy tipe van verklaring weerhou en geen waarde kan daaraan toegeken word behalwe waardes van sy verklaringtipe nie. Statiese programmeertale bied ekstra veiligheid wanneer hulle met tipes handel, maar kan die ontwikkelingsproses in sekere gebruiksgevalle vertraag wanneer dit 'n harde beperking word.

Dinamiese programmeertale

Dinamiese programmeertale, aan die ander kant, pas tipe-kontrole toe tydens looptyd. Dit beteken dat enige veranderlike enige waarde op enige punt in die program kan hou. Dit kan voordelig wees aangesien dit 'n vlak van buigsaamheid aan die ontwikkelaar bied wat nie in die statiese tale teenwoordig is nie. Dinamiese tale is geneig om stadiger uit te voer as hul statiese eweknieë, aangesien dit 'n bykomende stap behels om die tik van elke veranderlike dinamies uit te vind.

Monkey Patch

Statiese vs dinamiese tik is 'n fundamentele eienskap in 'n programmeertaal, wat met een paradigma oor die ander gaan, kan 'n magdom verskillende patrone en praktyke moontlik maak wat die kwaliteit en die spoed van ontwikkeling aansienlik kan verbeter. Dit kan ook die deur oopmaak vir baie beperkings en anti-patrone as daar nie noukeurige oorwegings gegee word wanneer ontwerpbesluite geneem word nie.

Dit is veral bekend dat dinamies getikte programmeertale 'n hoër vlak van buigsaamheid bied, aangesien hulle nie 'n veranderlike tot 'n enkele tipe beperk nie. Hierdie buigsaamheid kom met die koste van bykomende verantwoordelikheid aan die ontwikkelaar by die implementering en ontfouting van programme om seker te maak dat geen onvoorspelbare gedrag voorkom nie. Die aapvlekpatroon kom uit hierdie filosofie.

Monkey Patch verwys na die proses van uitbreiding/verandering van die werking van 'n komponent tydens looptyd. Die betrokke komponent kan 'n biblioteek, 'n klas, 'n metode of selfs 'n module wees. Die idee is dieselfde: 'n stukkie kode word gemaak om 'n sekere taak uit te voer, en die doel van aappleistering is om die gedrag van daardie stukkie kode te verander of uit te brei sodat dit 'n nuwe taak verrig, alles sonder om die kode self te verander .

Dit word moontlik gemaak in dinamiese programmeertaal aangesien dit nie saak maak met watter tipe komponent ons te doen het nie, dit het steeds dieselfde struktuur van 'n objek met verskillende eienskappe, die eienskappe kan metodes bevat wat hertoegewys kan word om 'n nuwe gedrag in die objek te bereik sonder om in te gaan op die interne en besonderhede van implementering. Dit word veral nuttig in die geval van derdeparty-biblioteke en -modules, aangesien dit geneig is om moeiliker te wees om aan te pas.

Die volgende voorbeeld sal 'n algemene gebruiksgeval ten toon stel wat kan baat by die gebruik van die aappleistertegniek. Javascript is ter wille van implementering hier gebruik, maar dit behoort steeds breedweg van toepassing te wees op enige ander dinamiese programmeertaal.

Voorbeeld

Implementeer 'n minimale toetsraamwerk met Node se inheemse HTTP-module

Eenheid- en integrasietoetsing kan onder die gebruiksgevalle van Monkey-patching val. Dit behels gewoonlik toetsgevalle wat oor meer as een diens strek vir integrasietoetsing, of API- en/of databasisafhanklikhede vir eenheidtoetsing. In hierdie twee scenario's, en om die doelwitte van toetsing in die eerste plek te bereik, wil ons hê dat ons toetse onafhanklik van hierdie eksterne hulpbronne moet wees. Die manier om dit te bereik is deur bespotting. Bespotting simuleer die gedrag van eksterne dienste sodat die toets op die werklike logika van die kode kan fokus. Monkey patching kan hier nuttig wees, aangesien dit die metodes van die eksterne dienste kan verander deur dit te vervang met plekhouermetodes wat ons "stub" noem. Hierdie metodes gee die verwagte resultaat in die toetsgevalle terug, sodat ons kan vermy om versoeke aan produksiedienste te begin net ter wille van toetse.

Die volgende voorbeeld is 'n eenvoudige implementering van Monkey-patching op die NodeJs inheemse http-module. Die http-module is die koppelvlak wat die http-protokolmetodes vir NodeJs implementeer. Dit word hoofsaaklik gebruik om barebone http-bedieners te skep en met eksterne dienste te kommunikeer deur die http-protokol te gebruik.

In die voorbeeld hieronder het ons 'n eenvoudige toetsgeval waar ons 'n eksterne diens bel om die lys gebruikers-ID's te gaan haal. Eerder as om die werklike diens te bel, pleister ons die http get-metode sodat dit net die verwagte resultaat gee, wat 'n verskeidenheid ewekansige gebruiker-ID's is. Dit lyk dalk nie van groot belang nie aangesien ons net data haal, maar as ons 'n ander toetsgeval implementeer wat die verandering van data van een of ander aard behels, kan ons per ongeluk data oor produksie verander wanneer toetse uitgevoer word.

Op hierdie manier kan ons ons funksionaliteite implementeer, en toetse skryf vir elke funksionaliteit terwyl ons die veiligheid van ons produksiedienste verseker.

// 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");
});

Die kode hierbo is eenvoudig, ons voer die http-module in, herken die http.get-metode met 'n nuwe metode wat net 'n verskeidenheid ID's terugstuur. Nou roep ons die nuwe gelapte metode binne die toetskassie en ons kry die nuwe verwagte resultaat.

~/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.

Algemene slaggate en beperkings

Dit behoort geen verrassing te wees dat aappleistering sy eie foute en beperkings het nie. In die konteks van modules in die nodus-modulestelsel, word die pleister van 'n globale module soos http as 'n bewerking met newe-effekte beskou, dit is omdat http toeganklik is vanaf enige punt binne die kodebasis en enige ander entiteit kan 'n afhanklikheid daarvan hê. Hierdie entiteite verwag dat die http-module in sy gewone gedrag sal werk, deur een van die http-metodes te verander, breek ons ​​effektief alle ander http-afhanklikhede binne die kodebasis.

Aangesien ons binne 'n dinamies getikte taal werk, sal dinge dalk nie dadelik misluk nie en sal eerder 'n onvoorspelbare gedrag gebruik wat ontfouting 'n uiters komplekse taak maak. In ander gebruiksgevalle kan daar twee verskillende kolle van dieselfde komponent op dieselfde kenmerk wees, in welke geval ons nie regtig kan voorspel watter pleister voorrang bo die ander sal geniet nie, wat lei tot 'n selfs meer onvoorspelbare kode.

Dit is ook belangrik om te noem dat aappleistering geringe variasies in gedrag tussen verskillende programmeertale kan hê. Dit hang alles af van die taalontwerp en keuses van implementering. Byvoorbeeld, in python sal nie alle gevalle wat 'n gelapte metode gebruik, deur die pleister geraak word nie. As 'n instansie die gelapte metode uitdruklik noem, sal dit die nuwe opgedateerde weergawe kry, inteendeel, ander instansies wat dalk net eienskappe het wat na die gelapte metode verwys en dit nie uitdruklik noem nie, sal die oorspronklike weergawe kry, dit is as gevolg van hoe python binding in klasse werk.

Gevolgtrekking

In hierdie artikel het ons die hoëvlak-onderskeidings tussen statiese en dinamiese programmeertale ondersoek, ons het gesien hoe dinamiese programmeertale voordeel kan trek uit nuwe paradigmas en patrone wat die inherente buigsaamheid wat hierdie tale bied, benut. Die voorbeeld wat ons ten toon gestel het, hou verband met Monkey-patching, 'n tegniek wat gebruik word om die gedrag van kode uit te brei sonder om dit van die bron af te verander. Ons het 'n geval gesien waar die gebruik van hierdie tegniek voordelig sou wees saam met die moontlike nadele daarvan. Sagteware-ontwikkeling gaan alles oor afwykings, en om die regte oplossing vir die probleem te gebruik, vereis uitgebreide oorwegings van die ontwikkelaar en 'n goeie begrip van argitektuurbeginsels en -grondbeginsels.


Career Services background pattern

Loopbaandienste

Contact Section background image

Kom ons bly in kontak

Code Labs Academy © 2024 Alle regte voorbehou.