Ռեսուրսի ստանալն ինիցիալիզացիա է

Ռեսուրսի ստանալն ինիցալիզացիա է () նախագծման ձևանմուշն իրենից ներկայացնում է օբյեկտ կողմնորոշված ծրագրավորման ստեղծման ձևանմուշ։ Այստեղ ծրագրավորման որոշակի ռեսուրսների ստանալը անխզելիորեն համատեղվում է ինիցիալիզացիայի հետ, իսկ ազատումը՝ օբյեկտի վերացման հետ։

Նման վարքագծի տիպիկ օրինակ է, բայց և ոչ միակը, ռեսուրսների ստացումը կոնստրուկտորների միջոցով իրագործելը, իսկ ազատումը համապատասխան դասի դեստրուկտորների միջոցով իրականացնելը։ Քանի որ դեստրուկտորն ավտոմատ կերպով կանչվում է ծրագրի դուրս գալուց, ապա ռեսուրսը հաստատապես կազատվի փոփոխականի վերացումից հետո։ Այս պնդումը ճիշտ է նույնիսկ այն դեպքում, երբ ծրագիրն ունի բացառություններ։ Դրա պատճառով էլ RAII-ն հանդիսանում է առանցքային հասկացություն ծրագրավորման լեզուներում բացառությունների մշակման համար, որտեղ օբյեկտների կոնստրուկտորներն ու դեստրուկտորները կանչվում են ավտոմատ կերպով (օրինակ C++ լեզվում)։

Ընդհանուր հասկացողություններ
 Client - հայցող
 Instance - նմուշ
 Implementation - իրականացում
 Product - արգասիք
 Exception - բացառում

Կիրառություն
Այս հասկացությունը կարող է օգտագործվել բոլոր բաշխվող օբյեկտների կամ ռեսուրսների համար.
 դինամիկ հիշողություն հատկացնելու համար
 ֆայլերի կամ սարքավորումների բացման համար
 մյուտեքսների կամ կրիտիկական սեկցիաների համար

RAII -ի կարևոր օգտագործում է հանդիսանում «խելացի ցուցիչները»` դասերը, ինկապսուլյացիայի միջոցով դինամիկ հիշողության կառավարումը։ Օրինակ, C++ լեզվի կաղապարների ստանդարտ գրադարանում այս նպատակի համար գոյություն ունի auto_ptr դասը (C++11-ում այն փոխարինվել է unique_ptr դասով)։

Առավելություններ
RAII-ի ռեսուրսների ղեկավարման մեթոդիկայի առավելությունն այն է, որ այն ապահովում է ինկապսուլյացիա, բացառումների անվտանգություն (ստեկի () ռեսուրսների համար) և լոկալություն (դա թույլ է տալիս ստացումն () ու տրամաբանական իրականացումը գրել կողք-կողքի)։

Ինկապսուլյացիան տրամադրվում է, քանի որ ռեսուրսների տրամադրման տրամաբանությունը դասի մեջ բնորոշվում է մեկ անգամ, այլ ոչ թե ամեն կանչի ժամանակ։ Բացառումների անվտանգությունը տրամադրվում է ստեկի ռեսուրսների համար (ռեսուրսներ, որոնք հատկացվում են ճիշտ այն ծավալով, որոնք որ նրանք ձեռք են բերել)` ռեսուրսի կյանքի տևողությունը կապելով ստեկի փոփոխականի հետ։ Եթե առաջ է եկել բացառում և բացառման մշակումը գտնվում է իր տեղում, միայն ծրագիրը, որը պետք է իրականացվի ընթացիք տարածքից դուրս գալու համար, հանդիսանում է տվյալ տարածքում հայտարարված օբյեկտների դեստրուկտոր։ Ի վերջո, դասում կոնստրուկտորն ու դեստրուկտորը հայտարարվում են կողք-կողքի՝ դասի բնորոշման մեջ։

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

RAII-ն համեմատելով Java-այում օգտագործվող finallyկոդի հետ, Ստրաստուպն ասել է. Իրական համակարգերում գոյություն ունեն ավելի շատ ռեսուրսների հատկացումներ, քան ռեսուրսների տեսակներն են։ Այսպիսով «Ռեսուրսի ստանալը ինիցիալիզացիա է» տեխնիկան բերում է ծրագրավորման կոդի ավելի փոքր չափերի, քան finally կոնստրուկցիան է։

C++11 լեզվով օրինակ
Հետևյալ օրինակը ցույց է տալիս RAII-ի օգտագործումը մյուտեքսը  կողպենքելու համար.
#include <string>
#include <mutex>
#include <iostream>
#include <fstream>
#include <stdexcept>

void write_to_file (const std::string & message) {
    // mutex to protect file access
    static std::mutex mutex;

    // lock mutex before accessing file
    std::lock_guard<std::mutex> lock(mutex);

    // try to open file
    std::ofstream file("example.txt");
    if (!file.is_open())
        throw std::runtime_error("unable to open file");
    
    // write message to file
    file << message << std::endl;
    
    // file will be closed 1st when leaving scope (regardless of exception)
    // mutex will be unlocked 2nd (from lock destructor) when leaving
    // scope (regardless of exception)
}

Այս կոդը հանդիսանում է անվտանգության բացառում, քանի որ C ++ լեզուն երաշխավորում է, որ բոլոր օբյեկտները կվերացվեն ծրագրի ավարտից հետո։ Ֆայլերի և արգելափակիչների () դեստրուկտորներն երաշխավորված կերպով կանչվում են ֆունկցիայի կանչից հետո՝ անկախ նրանից թե ծրագրի կոդը բացառություն նետում է, թե ոչ։

Լոկալ փոփոխականները թույլ են տալիս մի ֆունկցիայի շրջանակներում հեշտությամբ կառավարել մի քանի ռեսուրսներ։ Ռեսուրսները վերանում են ըստ ստեղծման հակառակ հերթականության, իսկ օբյեկտը վերացվում է միայն այն դեպքում, երբ այն ամբողջովին կառուցված է։ Այսինքն բացառումը չի տարածվում իր սեփական կոնստրուկտորի վրայից։

RAII-ի օգտագործումը զգալիորեն հեշտացնում է ռեսուրսների կառավարումը, փոքրացնում է ընդհանուր ծրագրային կոդի ծավալը և օգնում է երաշխավորել ծրագրի կոռեկտությունը։ Այդ պատճառով էլ այն խստորեն խորհուրդ է տրվում օգտագործել C++ լեզվում և լեզվի ստանդարտ գրադարաններից մեծամասնությունն հետևում է այդ կանոնին։

Ծանոթագրություններ 

Ծրագրավորում