Кіріспе

Процесстің өзін-өзі зерделеу және өзгерту мүмкіндігі

Компьютер ғылымында рефлексивті бағдарламалау немесе рефлексия – процестің өз құрылымын және әрекетін зерделеу, талдау және өзгерту қабілеті.

Тарихи негіздер

Алғашқы компьютерлер өздерінің түпкілікті тілдерінде, яғни тікелей машиналық кодта бағдарламаланған, бұл тілдер өзіндік бейнелеу қабілетіне ие болды. Себебі, бұл бастапқы архитектуралар нұсқауларды дерек ретінде анықтап, өзін-өзі өзгертетін кодты пайдалану арқылы бағдарламаланатын еді. Бағдарламалаудың көп бөлігі Algol, Cobol, Fortran, Pascal және C сияқты жоғары деңгейдегі компиляцияланатын тілдерге көшкен кезде, бұл бейнелеу қабілеті жоғалып, жаңа бағдарламалау тілдері, олардың типтік жүйелеріне бейнелеу мүмкіндігі енгізілгенше қайта пайда болмады. Брайан Кантуэлл Смиттің 1982 жылғы докторлық диссертациясы процедуралық бағдарламалау тілдеріндегі есептеулік рефлексия және 3 Lisp құрамындағы мета-циклдық интерпретатор ұғымдарын енгізді.

Қолданылуы

Рефлексия бағдарламашыларға деректерді көрсету, әртүрлі форматтағы деректерді өңдеу, байланыс үшін деректерді серияландыру және десериализациялау, контейнерлер немесе байланыс пакеттері үшін деректерді біріктіру және бөлу үшін жалпы бағдарламалық кітапханалар жасауға көмектеседі. Рефлексияны тиімді пайдалану үшін әрқашан жоспар қажет: жобалау шеңбері, кодтау сипаттамасы, объект кітапханасы, деректер базасының картасы немесе объектілер арасындағы қатынастар. Рефлексия тілді желілік бағдарланған кодқа сәйкес етуге көмектеседі. Мысалы, Java сияқты тілдерге серияландыру, біріктіру және әртүрлі деректер форматтарын қолдау үшін кітапханаларды іске қосу арқылы желілерде жақсы жұмыс істеуге мүмкіндік береді. C сияқты рефлексиясы жоқ тілдерге серияландыру және біріктіру үшін код жасау үшін абстрактілі синтаксистік нотация сияқты тапсырмалар үшін қосымша компиляторлар қажет. Рефлексия бағдарламаның орындалуын орындау кезінде бақылау және өзгерту үшін қолданылуы мүмкін. Рефлексияға бағытталған бағдарламалық компонент кодтың бөлігінің орындалуын бақылап, осы бөліктің қажетті мақсатына сәйкес өзін өзгерте алады. Бұл әдетте бағдарламалық кодты орындау кезінде динамикалық түрде тағайындау арқылы жүзеге асырылады. Java сияқты объектіге бағытталған бағдарламалау тілдерінде рефлексия кластарды, интерфейстерді, өрістерді және әдістерді орындау кезінде, олардың атауларын компиляция кезінде білмей тексеруге мүмкіндік береді. Сондай-ақ, жаңа объектілерді құруға және әдістерді шақыруға мүмкіндік береді. Рефлексия көбінесе бағдарламалық қамтамасыз етуді сынау кезінде, мысалы, іске қосылған кезде макеттік объектілерді жасау/инстанциялау үшін қолданылады. Рефлексия – метапрограммалаудың маңызды стратегиясы. Кейбір объектіге бағытталған бағдарламалау тілдерінде, мысалы C# және Java, мүшенің қолжетімділік ережелерін айналып өту үшін рефлексияны пайдалануға болады. C# қасиеттері үшін бұл тікелей (әдетте көрінбейтін) мемлекеттік емес қасиеттің қолдау өрісіне жазу арқылы жүзеге асырылуы мүмкін. Сондай-ақ, кластар мен типтердің жеке әдістерін табу және оларды қолмен шақыру мүмкін. Бұл жобаның ішкі файлдарымен қатар, NET жиналымдары мен Java архивтері сияқты сыртқы кітапханалар үшін де жұмыс істейді.

Іске асыру

Рефлексияны қолдайтын тіл, төменгі деңгейдегі тілде орындау қиын болатын көптеген мүмкіндіктерді орындалу кезінде ұсынады. Осы мүмкіндіктердің кейбіреулері: бастапқы код құрылымдарын (код блоктары, сыныптар, әдістер, протоколдар және т.б.) орындалу кезінде бірінші дәрежелі нысандар ретінде табу және өзгерту; сынып немесе функция символдық атына сәйкес келетін жолды сол сыныпқа немесе функцияға сілтемеге немесе шақыруға түрлендіру; орындалу кезінде жолды бастапқы кодтың операторы ретінде бағалау; бағдарламалық құрылымға жаңа мағына немесе мақсат беру үшін тілдің байт-коды үшін жаңа интерпретатор жасау. Бұл мүмкіндіктерді әртүрлі тәсілдермен жүзеге асыруға болады. MOO-да рефлексия күнделікті бағдарламалау стилінің табиғи бөлігі болып табылады. Әдістер (әдістер) шақырғанда, әр түрлі айнымалылар, мысалы, әдіс (шақырылып жатқан әдістің аты) және осы (әдіс шақырылған нысан) шақыру контекстін беру үшін толтырылады. Қауіпсіздік әдетте шақырушы стегіне бағдарламалық түрде қол жеткізу арқылы басқарылады: шақырушылар – ағымдағы әдіс ақырында шақырылған әдістердің тізімі болғандықтан, шақырушылар[0] (түпнұсқа пайдаланушы шақырған команда) бойынша тесттер жүргізу әдісті рұқсатсыз пайдаланудан қорғауға мүмкіндік береді. Компиляцияланған тілдер бастапқы код туралы ақпаратты беру үшін орындалу уақытына сенеді. Мысалы, компиляцияланған Objective C атқарылатын файлы бағдарламаға компиляцияланған негізгі әдістермен (немесе осы әдістердің таңдағыштарымен) сәйкес келетін кестемен қамтамасыз ете отырып, атқарылатын файлдың блогындағы барлық әдістердің атауларын жазады. Common Lisp сияқты орындалу уақытында функцияларды жасауды қолдайтын компиляцияланған тілде, орындалу ортасында компилятор немесе интерпретатор болуы керек. Рефлексияны қолдамайтын тілдер үшін, бағдарламалық түрлендіру жүйесін пайдаланып, автоматтандырылған бастапқы кодтың өзгерістерін анықтау арқылы жүзеге асыруға болады.

Қауіпсіздік мәселелері

Айналу пайдаланушыға қосымша арқылы күтпеген басқару ағыны жолдарын жасауға мүмкіндік береді, бұл қауіпсіздік шараларын айналып өтуге әкелуі мүмкін. Бұл шабуылшылар үшін пайдаланылуы мүмкін. Java-дағы қауіпсіз рефлексияға байланысты бұрынғы осалдықтар, Java қауіпсіздік ортасынан шығуға мүмкіндік беріп, сенімсіз қашықтан алынған кодты іске қосуға жол берді. 2013 жылы жүргізілген 120 Java осалдығын қамтитын зерттеуде, Java-да қауіпсіз рефлексия ең көп кездесетін осалдық екені, бірақ ең көп пайдаланылмайтыны анықталды.

Мысалдар

Келесі код үзінділері класс инстанциясын құрады және оның әдісін шақырады. Әр бағдарламалау тілі үшін қалыпты және рефлексия негізіндегі шақыру тізбектері көрсетілген.