Monkey Patching դինամիկ ծրագրավորման լեզուներով. JavaScript-ի օրինակ

Javascript
Դինամիկ ծրագրավորում
Monkey Patching դինամիկ ծրագրավորման լեզուներով cover image

Ներածություն

Այս հոդվածը կուսումնասիրի դինամիկ և ստատիկ ծրագրավորման լեզուների հասկացությունները, երկուսի միջև եղած հիմնական տարբերությունները և այն, ինչ յուրաքանչյուր պարադիգմ է տալիս առավելությունների և թակարդների առումով: Այս ուսումնասիրությունը հետագայում կկենտրոնանա դինամիկ ծրագրավորման լեզուների վրա, մասնավորապես այն հիմնական օրինաչափություններից մեկի վրա, որը թույլ է տալիս. Monkey Patch, այս օրինաչափությունը կցուցադրվի JavaScript օրինակի օգնությամբ:

Դինամիկ ընդդեմ ստատիկ ծրագրավորման լեզուների

Տերմինաբանություն

Որպեսզի հասկանանք, թե ինչ է իրենից ներկայացնում դինամիկ կամ ստատիկ լեզու, մենք պետք է հասկանանք մի քանի հիմնական տերմիններ, որոնք սովորաբար օգտագործվում են այս համատեքստում. *.

Compile-ը և Runtime-ը երկու տերմին են, որոնք համապատասխանում են համակարգչային ծրագրի կյանքի ցիկլի տարբեր փուլերին՝ սկսած Compile time-ից:

Կազմելու ժամանակը

Կազմելու ժամանակը ծրագրի կյանքի ցիկլի առաջին քայլն է: Մշակողը գրում է կոդը տվյալ ծրագրավորման լեզվով: Ավելի հաճախ, քան ոչ, մեքենան չի կարողանում հասկանալ բարձր մակարդակի լեզվով գրված կոդը, ուստի օգտագործվում է հատուկ կոմպիլյատոր՝ այն թարգմանելու ավելի ցածր մակարդակի միջանկյալ ձևաչափի, որը պատրաստ է դառնում կատարման:

Runtime

Runtime-ը սովորաբար ներառում է երկու քայլ՝ բեռնել ծրագիրը հիշողության մեջ՝ բաշխելով դրա կատարման համար անհրաժեշտ ռեսուրսները՝ իր հրահանգների հետ միասին, և այնուհետև ծրագիրը գործարկել՝ հետևելով այդ հրահանգների հերթականությանը:

Հետևյալ դիագրամը ցույց է տալիս այս գործընթացը.

Տիպի ստուգում

Տիպի ստուգումը ներկառուցված գործառույթ է գրեթե բոլոր ծրագրավորման լեզուներում: Դա հնարավորություն է ստուգելու, թե արդյոք տվյալ փոփոխականին վերագրված արժեքը համապատասխանում է այդ փոփոխականի ճիշտ տեսակին: Ծրագրավորման յուրաքանչյուր լեզու ունի հիշողության մեջ տվյալ տեսակի արժեքը ներկայացնելու տարբեր ձև: Այս տարբեր ներկայացումները հնարավորություն են տալիս ստուգել արժեքի տեսակի և փոփոխականի տեսակի միջև համապատասխանությունը, որին փորձում եք վերագրել այդ արժեքը:

Այժմ, երբ մենք ունենք ծրագրի կյանքի ցիկլի և տիպի ստուգման բարձր մակարդակի պատկերացում, մենք կարող ենք անցնել ստատիկ ծրագրավորման լեզուների ուսումնասիրությանը:

Ստատիկ ծրագրավորման լեզուներ

Ստատիկ ծրագրավորման լեզուները, որոնք նաև կոչվում են ստատիկ տպագրված լեզուներ, այն լեզուներն են, որոնք կիրառում են տիպի ստուգումը, որը մենք նշեցինք կոմպիլյացիայի փուլում: Սա փաստորեն նշանակում է, որ փոփոխականը պահում է իր տեսակը հայտարարագրումից և որևէ արժեք չի կարող վերագրվել նրան, բացի իր հայտարարագրման տեսակի արժեքներից: Ստատիկ ծրագրավորման լեզուներն առաջարկում են լրացուցիչ անվտանգություն տեսակների հետ գործ ունենալիս, սակայն կարող են դանդաղեցնել զարգացման գործընթացը որոշ օգտագործման դեպքերում, երբ դա դառնում է խիստ սահմանափակում:

Դինամիկ ծրագրավորման լեզուներ

Մյուս կողմից, դինամիկ ծրագրավորման լեզուները կիրառում են տիպի ստուգում գործարկման ժամանակ: Սա նշանակում է, որ ցանկացած փոփոխական կարող է ցանկացած արժեք պահել ծրագրի ցանկացած կետում: Սա կարող է օգտակար լինել, քանի որ այն ծրագրավորողին առաջարկում է ճկունության այնպիսի մակարդակ, որն առկա չէ ստատիկ լեզուներում: Դինամիկ լեզուները հակված են ավելի դանդաղ կատարման, քան իրենց ստատիկ գործընկերները, քանի որ դրանք ներառում են յուրաքանչյուր փոփոխականի մուտքագրումը դինամիկ կերպով պարզելու լրացուցիչ քայլ:

Monkey Patch

Static vs Dynamic Typing-ը ծրագրավորման լեզվի հիմնական հատկանիշն է, որը մեկ պարադիգմով մյուսի վրա անցնելը կարող է հնարավորություն տալ մի շարք տարբեր օրինաչափությունների և պրակտիկաների, որոնք կարող են զգալիորեն բարելավել զարգացման որակը և արագությունը: Այն կարող է նաև բացել բազմաթիվ սահմանափակումների և հակաօրինաչափությունների դուռ, եթե դիզայնի որոշումներ կայացնելիս ուշադիր նկատառումներ չտրվեն:

Մասնավորապես, հայտնի է, որ դինամիկ տպագրված ծրագրավորման լեզուներն առաջարկում են ճկունության ավելի բարձր մակարդակ, քանի որ դրանք չեն սահմանափակում փոփոխականը մեկ տեսակի համար: Այս ճկունությունը կապված է ծրագրավորողի նկատմամբ լրացուցիչ պատասխանատվության հետ՝ ծրագրերի իրականացման և վրիպազերծման ժամանակ՝ համոզվելու համար, որ անկանխատեսելի վարքագիծ չի առաջանում: Կապիկների կարկատման ձևը գալիս է այս փիլիսոփայությունից:

Monkey Patch-ը վերաբերում է գործարկման ժամանակ բաղադրիչի աշխատանքը երկարացնելու/փոխելու գործընթացին: Քննարկվող բաղադրիչը կարող է լինել գրադարան, դաս, մեթոդ կամ նույնիսկ մոդուլ: Գաղափարը նույնն է. կոդի մի կտոր ստեղծվում է որոշակի առաջադրանք կատարելու համար, և կապիկի կարկատման նպատակն է փոխել կամ ընդլայնել այդ կոդի վարքագիծը, որպեսզի այն կատարի նոր առաջադրանք՝ առանց ինքնին կոդը փոխելու։ .

Դա հնարավոր է դարձել դինամիկ ծրագրավորման լեզվով, քանի որ անկախ նրանից, թե ինչ տեսակի բաղադրիչի հետ գործ ունենք, այն դեռ ունի տարբեր ատրիբուտներով օբյեկտի նույն կառուցվածքը, ատրիբուտները կարող են պարունակել մեթոդներ, որոնք կարող են վերանշանակվել օբյեկտում նոր վարքագծի հասնելու համար: առանց խորանալու դրա ներքին և իրականացման մանրամասների մեջ: Սա հատկապես օգտակար է դառնում երրորդ կողմի գրադարանների և մոդուլների դեպքում, քանի որ դրանք ավելի դժվար է կսմթել:

Հետևյալ օրինակը կցուցադրի սովորական օգտագործման դեպք, որը կարող է օգուտ քաղել կապիկների կարկատման տեխնիկայի օգտագործումից: Javascript-ն օգտագործվել է այստեղ իրագործման համար, բայց դա դեռ պետք է լայնորեն կիրառվի ցանկացած այլ դինամիկ ծրագրավորման լեզվի համար:

Օրինակ

Իրականացրեք նվազագույն փորձարկման շրջանակ Node-ի բնիկ HTTP մոդուլով

Միավորների և ինտեգրման փորձարկումները կարող են ընկնել Monkey patching-ի օգտագործման դեպքերի ներքո: Դրանք սովորաբար ներառում են թեստային դեպքեր, որոնք ընդգրկում են մեկից ավելի ծառայություններ ինտեգրման թեստավորման համար, կամ API-ի և/կամ տվյալների բազայի կախվածությունը միավորի փորձարկման համար: Այս երկու սցենարներում, և առաջին հերթին թեստավորման նպատակներն իրականացնելու համար մենք կցանկանայինք, որ մեր թեստերը անկախ լինեն այս արտաքին ռեսուրսներից: Դրան հասնելու ճանապարհը ծաղրի միջոցով է: Ծաղրը արտաքին ծառայությունների վարքագծի մոդելավորումն է, որպեսզի թեստը կարողանա կենտրոնանալ կոդի իրական տրամաբանության վրա: Կապիկների կարկատումը կարող է օգտակար լինել այստեղ, քանի որ այն կարող է փոփոխել արտաքին ծառայությունների մեթոդները՝ դրանք փոխարինելով տեղապահ մեթոդներով, որոնք մենք անվանում ենք «անավ»: Այս մեթոդները վերադարձնում են ակնկալվող արդյունքը թեստավորման դեպքերում, որպեսզի կարողանանք խուսափել արտադրական ծառայություններին հարցումներ սկսելուց միայն թեստերի համար:

Հետևյալ օրինակը Monkey patching-ի պարզ իրականացումն է NodeJs մայրենի http մոդուլի վրա: http մոդուլը ինտերֆեյս է, որն իրականացնում է http արձանագրության մեթոդները NodeJ-ների համար։ Այն հիմնականում օգտագործվում է barebone http սերվերներ ստեղծելու և արտաքին ծառայությունների հետ շփվելու համար՝ օգտագործելով http արձանագրությունը։

Ստորև բերված օրինակում մենք ունենք մի պարզ փորձարկման դեպք, որտեղ մենք կանչում ենք արտաքին ծառայություն՝ օգտատերերի ID-ների ցանկը ստանալու համար: Փաստացի ծառայությունը կանչելու փոխարեն մենք կարկատում ենք http get մեթոդը, այնպես որ այն պարզապես վերադարձնում է ակնկալվող արդյունքը, որը պատահական օգտագործողի ID-ների զանգված է: Սա կարող է մեծ նշանակություն չթվալ, քանի որ մենք պարզապես տվյալներ ենք վերցնում, բայց եթե մենք իրականացնենք մեկ այլ թեստային դեպք, որը ներառում է որևէ տեսակի տվյալների փոփոխություն, մենք կարող ենք պատահաբար փոխել արտադրության տվյալները՝ փորձարկումների ընթացքում:

Այս կերպ մենք կարող ենք իրականացնել մեր գործառույթները և գրել թեստեր յուրաքանչյուր ֆունկցիոնալության համար՝ միաժամանակ երաշխավորելով մեր արտադրական ծառայությունների անվտանգությունը:

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

Վերևի կոդը պարզ է, մենք ներմուծում ենք http մոդուլը, վերահանձնում http.get մեթոդը նոր մեթոդով, որը պարզապես վերադարձնում է ID-ների զանգված: Այժմ մենք կանչում ենք նոր կարկատված մեթոդը թեստային գործի ներսում և ստանում ենք նոր ակնկալվող արդյունքը:

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

Ընդհանուր որոգայթներ և սահմանափակումներ

Զարմանալի չէ, որ կապիկների կարկատումն ունի իր թերություններն ու սահմանափակումները: Հանգույցային մոդուլային համակարգի մոդուլների համատեքստում գլոբալ մոդուլի կարկատումը, ինչպիսին է http-ը, համարվում է կողմնակի ազդեցություններով օպերացիա, քանի որ http-ը հասանելի է կոդերի բազայի ցանկացած կետից, և ցանկացած այլ միավոր կարող է կախվածություն ունենալ դրանից: Այս սուբյեկտները ակնկալում են, որ http մոդուլը կգործի իր սովորական վարքագծով, փոխելով http մեթոդներից մեկը, մենք արդյունավետորեն կոտրում ենք բոլոր մյուս http կախվածությունները կոդի բազայի ներսում:

Քանի որ մենք աշխատում ենք դինամիկ տպագրված լեզվով, ամեն ինչ կարող է անմիջապես ձախողվել և ավելի շուտ անկանխատեսելի վարքագիծ դրսևորել, ինչը վրիպազերծումը դարձնում է չափազանց բարդ խնդիր: Օգտագործման այլ դեպքերում կարող են լինել նույն բաղադրիչի երկու տարբեր պատչեր միևնույն հատկանիշի վրա, որի դեպքում մենք իրականում չենք կարող կանխատեսել, թե որ պատչը կգերակայի մյուսին, ինչը կհանգեցնի ավելի անկանխատեսելի կոդ:

Կարևոր է նաև նշել, որ կապիկների կարկատումը կարող է փոքր-ինչ տատանումներ ունենալ տարբեր ծրագրավորման լեզուների միջև: Ամեն ինչ կախված է լեզվի ձևավորումից և իրականացման ընտրությունից: Օրինակ, python-ում ոչ բոլոր օրինակներն են, որոնք օգտագործում են կարկատված մեթոդը, կազդի կարկատման վրա: Եթե ​​օրինակը բացահայտորեն կանչում է կարկատված մեթոդը, ապա այն կստանա նոր թարմացված տարբերակը, ընդհակառակը, մյուս օրինակները, որոնք կարող են ունենալ միայն կարկատված մեթոդի վրա մատնանշող ատրիբուտներ և այն հստակորեն չկանչելը, կստանան սկզբնական տարբերակը, դա պայմանավորված է, թե ինչպես է python-ը: գործում է պարտադիր դասերում:

Եզրակացություն

Այս հոդվածում մենք ուսումնասիրեցինք ստատիկ և դինամիկ ծրագրավորման լեզուների բարձր մակարդակի տարբերությունները, տեսանք, թե ինչպես կարող են դինամիկ ծրագրավորման լեզուները օգտվել նոր պարադիգմներից և օրինաչափություններից, որոնք օգտագործում են այս լեզուների բնորոշ ճկունությունը: Մեր ցուցադրած օրինակը կապված էր Monkey patching-ի հետ, մի տեխնիկա, որն օգտագործվում է կոդի վարքագիծը ընդլայնելու համար՝ առանց այն փոխելու աղբյուրից: Մենք տեսանք մի դեպք, երբ այս տեխնիկայի օգտագործումը շահավետ կլիներ դրա հնարավոր թերությունների հետ մեկտեղ: Ծրագրային ապահովման մշակումը կապված է փոխզիջումների հետ, և խնդրի ճիշտ լուծումը կիրառելը պահանջում է մշակողի կողմից մանրամասն նկատառումներ և ճարտարապետության սկզբունքների և հիմունքների լավ իմացություն:


Career Services background pattern

Կարիերայի ծառայություններ

Contact Section background image

Եկեք մնանք կապի մեջ

Code Labs Academy © 2024 Բոլոր իրավունքները պաշտպանված են.