Monkey Patching у мовах дынамічнага праграмавання: прыклад JavaScript

Javascript
дынамічнае праграмаванне
Monkey Patching у мовах дынамічнага праграмавання cover image

Уводзіны

У гэтым артыкуле будуць даследаваны канцэпцыі дынамічнай і статычнай моў праграмавання, асноўныя адрозненні паміж імі і перавагі і недахопы кожнай парадыгмы. У далейшым гэтае даследаванне будзе сканцэнтравана на дынамічных мовах праграмавання, у прыватнасці, на адным з асноўных шаблонаў, якія яны дазваляюць: Monkey Patch, гэты шаблон будзе прадэманстраваны з дапамогай прыкладу ў JavaScript.

Дынамічныя і статычныя мовы праграмавання

Тэрміналогія

Каб зразумець, што такое дынамічная ці статычная мова, нам неабходна зразумець некалькі ключавых тэрмінаў, якія звычайна выкарыстоўваюцца ў гэтым кантэксце: Час кампіляцыі, Вас выканання і *Праверка тыпу *.

Кампіляцыя і час выканання - гэта два тэрміны, якія адпавядаюць розным этапам жыццёвага цыкла кампутарнай праграмы, пачынаючы з часу кампіляцыі.

Час кампіляцыі

Час кампіляцыі - гэта першы крок у жыццёвым цыкле праграмы. Распрацоўшчык піша код на зададзенай мове праграмавання. Часцей за ўсё машына не можа зразумець код, напісаны на мове высокага ўзроўню, таму спецыяльны кампілятар выкарыстоўваецца для яго перакладу ў прамежкавы фармат больш нізкага ўзроўню, які становіцца гатовым да выканання.

Час выканання

Асяроддзе выканання звычайна ўключае ў сябе два этапы: загрузка праграмы ў памяць шляхам размеркавання рэсурсаў, неабходных для яе выканання разам з яе інструкцыямі, а затым выкананне праграмы ў адпаведнасці з парадкам гэтых інструкцый.

Наступная схема ілюструе гэты працэс:

Праверка тыпу

Праверка тыпу з'яўляецца ўбудаванай функцыяй практычна ва ўсіх мовах праграмавання. Гэта магчымасць праверыць, ці адпавядае значэнне, прысвоенае дадзенай зменнай, правільнаму тыпу гэтай зменнай. Кожная мова праграмавання мае свой спосаб прадстаўлення значэння дадзенага тыпу ў памяці. Гэтыя розныя прадстаўленні дазваляюць праверыць адпаведнасць паміж тыпам значэння і тыпам зменнай, якой вы спрабуеце прысвоіць гэтае значэнне.

Цяпер, калі ў нас ёсць глыбокае разуменне жыццёвага цыкла праграмы і праверкі тыпаў, мы можам перайсці да вывучэння статычных моў праграмавання.

Статычныя мовы праграмавання

Статычныя мовы праграмавання, якія таксама называюць мовамі са статычнай тыпізацыяй, - гэта мовы, у якіх прымяняецца праверка тыпаў, пра якую мы згадвалі на этапе кампіляцыі. Фактычна гэта азначае, што зменная захоўвае свой тып ад дэкларацыі і ніякае значэнне ёй не можа быць прысвоена, акрамя значэнняў з яе тыпу дэкларацыі. Статычныя мовы праграмавання забяспечваюць дадатковую бяспеку пры працы з тыпамі, але могуць запаволіць працэс распрацоўкі ў пэўных выпадках выкарыстання, калі гэта становіцца жорсткім абмежаваннем.

Мовы дынамічнага праграмавання

Дынамічныя мовы праграмавання, з іншага боку, прымяняюць праверку тыпу падчас выканання. Гэта азначае, што любая зменная можа ўтрымліваць любое значэнне ў любой кропцы праграмы. Гэта можа быць карысным, бо прапануе распрацоўшчыку ўзровень гнуткасці, якога няма ў статычных мовах. Дынамічныя мовы, як правіла, больш павольныя пры выкананні, чым іх статычныя аналагі, паколькі яны ўключаюць у сябе дадатковы этап дынамічнага высвятлення тыпу кожнай зменнай.

Monkey Patch

Статычная супраць дынамічнай тыпізацыі з'яўляецца фундаментальнай рысай у мове праграмавання, пераход ад адной парадыгмы да іншай можа дазволіць мноства розных шаблонаў і практык, якія могуць значна палепшыць якасць і хуткасць распрацоўкі. Гэта таксама можа адкрыць дзверы для многіх абмежаванняў і антышаблонаў, калі пры прыняцці дызайнерскіх рашэнняў не быць уважліва разгледжаны.

У прыватнасці, вядома, што мовы праграмавання з дынамічнай тыпізацыяй прапануюць больш высокі ўзровень гнуткасці, паколькі яны не абмяжоўваюць зменную адным тыпам. Гэтая гібкасць звязана з коштам дадатковай адказнасці распрацоўшчыка пры ўкараненні і адладцы праграм, каб пераканацца ў адсутнасці непрадказальных паводзін. Малпавая нашыўка паходзіць з гэтай філасофіі.

Monkey Patch адносіцца да працэсу пашырэння/змены працы кампанента падчас выканання. Разгляданы кампанент можа быць бібліятэкай, класам, метадам ці нават модулем. Ідэя тая ж: кавалак кода ствараецца для выканання пэўнай задачы, і мэта monkey patching - змяніць або пашырыць паводзіны гэтага фрагмента кода так, каб ён выконваў новую задачу, і ўсё без змены самога кода .

Гэта стала магчымым у дынамічнай мове праграмавання, паколькі незалежна ад таго, з якім тыпам кампанента мы маем справу, ён усё яшчэ мае тую ж самую структуру аб'екта з рознымі атрыбутамі, атрыбуты могуць утрымліваць метады, якія можна пераназначыць для дасягнення новых паводзін аб'екта. не ўдаючыся ў яго ўнутраныя дэталі і дэталі рэалізацыі. Гэта становіцца асабліва карысным у выпадку старонніх бібліятэк і модуляў, паколькі іх, як правіла, складаней наладзіць.

Наступны прыклад прадэманструе звычайны варыянт выкарыстання, які можа прынесці карысць ад выкарыстання тэхнікі малпавага патча. Javascript быў выкарыстаны ў мэтах рэалізацыі тут, але гэта ўсё яшчэ павінна шырока прымяняцца да любой іншай дынамічнай мовы праграмавання.

Прыклад

Рэалізуйце мінімальнае тэсціраванне з уласным HTTP-модулем Node

Модульнае і інтэграцыйнае тэставанне можа падпадаць пад варыянты выкарыстання Monkey patching. Звычайна яны ўключаюць тэставыя прыклады, якія ахопліваюць больш чым адну службу для інтэграцыйнага тэсціравання, або залежнасці API і/або базы дадзеных для модульнага тэсціравання. У гэтых двух сцэнарыях і для таго, каб у першую чаргу дасягнуць мэт тэставання, мы хацелі б, каб нашы тэсты былі незалежнымі ад гэтых знешніх рэсурсаў. Спосаб дасягнуць гэтага - здзек. Насмешка - гэта мадэляванне паводзін знешніх службаў, каб тэст мог засяродзіцца на сапраўднай логіцы кода. Monkey patching можа быць тут карысным, паколькі ён можа змяняць метады знешніх службаў, замяняючы іх метадамі запаўняльнікаў, якія мы называем «заглушкамі». Гэтыя метады вяртаюць чаканы вынік у выпадках тэставання, каб мы маглі пазбегнуць ініцыявання запытаў да вытворчых службаў толькі дзеля тэстаў.

Наступны прыклад - гэта простая рэалізацыя выпраўленняў Monkey на ўласным http-модулі NodeJ. Модуль http - гэта інтэрфейс, які рэалізуе метады пратаколу http для NodeJ. Ён у асноўным выкарыстоўваецца для стварэння http-сервераў barebone і сувязі са знешнімі службамі з дапамогай пратаколу http.

У прыведзеным ніжэй прыкладзе мы маем просты тэставы выпадак, калі мы выклікаем знешні сэрвіс, каб атрымаць спіс ідэнтыфікатараў карыстальнікаў. Замест таго, каб выклікаць сапраўдную службу, мы выпраўляем метад http get, каб ён проста вяртаў чаканы вынік, які ўяўляе сабой масіў выпадковых ідэнтыфікатараў карыстальнікаў. Гэта можа здацца не вельмі важным, паколькі мы проста здабываем даныя, але калі мы рэалізуем іншы тэставы прыклад, які прадугледжвае нейкае змяненне даных, мы можам выпадкова змяніць даныя аб вытворчасці падчас выканання тэстаў.

Такім чынам мы можам рэалізаваць нашы функцыянальныя магчымасці і напісаць тэсты для кожнай функцыянальнасці, гарантуючы бяспеку нашых вытворчых паслуг.

// 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 новым метадам, які проста вяртае масіў ідэнтыфікатараў. Цяпер мы выклікаем новы выпраўлены метад у тэставым выпадку і атрымліваем новы чаканы вынік.

~/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 Усе правы абароненыя.