Akuisisi Sumber Daya Adalah Inisialisasi berarti bahwa objek harus menjaga diri mereka sebagai paket lengkap dan tidak mengharapkan kode lain untuk memberi contoh "hei omong-omong, Anda akan segera dibersihkan - tolong bereskan sekarang." Biasanya ini berarti ada sesuatu yang bermakna dalam destruktor. Ini juga berarti Anda menulis kelas khusus untuk mengelola sumber daya, mengetahui bahwa dalam keadaan tertentu yang sulit diprediksi, seperti pengecualian yang dilemparkan, Anda dapat mengandalkan penghancur yang mengeksekusi.
Katakanlah Anda ingin menulis beberapa kode di mana Anda akan mengubah kursor windows menjadi kursor tunggu (jam pasir, donat tidak berfungsi, dll), lakukan hal-hal Anda, dan kemudian ubah kembali. Dan katakan juga bahwa "kerjakan barangmu" mungkin memberikan pengecualian. Cara RAII melakukan itu adalah membuat kelas yang ctornya mengatur kursor untuk menunggu, yang satu-satunya "nyata" metode melakukan apa pun yang Anda inginkan dilakukan, dan yang dtor mengatur kursor kembali. Sumber daya (dalam hal ini kondisi kursor) terikat ke ruang lingkup suatu objek. Ketika Anda memperoleh sumber daya Anda menginisialisasi objek. Anda dapat mengandalkan objek yang akan dihancurkan jika pengecualian dilemparkan, dan itu berarti Anda dapat mengandalkan untuk membersihkan sumber daya.
Menggunakan RAII dengan baik berarti Anda tidak perlu finally
. Tentu saja, ini bergantung pada kehancuran deterministik, yang tidak dapat Anda miliki di Jawa. Anda bisa mendapatkan semacam penghancuran deterministik dalam C # dan VB.NET dengan using
.
RAII sebagian tentang memutuskan kapan suatu objek menjadi bertanggung jawab atas pembersihannya sendiri - aturannya adalah bahwa objek menjadi bertanggung jawab jika dan ketika inisialisasi konstruktornya selesai. Simetri inisialisasi dan pembersihan, konstruktor dan destruktor, berarti keduanya memiliki ikatan yang erat satu sama lain.
Satu poin dari RAII adalah untuk memastikan keamanan pengecualian - bahwa aplikasi tetap konsisten saat pengecualian dilemparkan. Pada pandangan pertama ini sepele - ketika pengecualian menyebabkan ruang lingkup untuk keluar, variabel lokal dalam ruang lingkup itu perlu dihancurkan.
Tetapi apa yang terjadi jika lemparan eksepsi terjadi di dalam konstruktor?
Nah, objek belum sepenuhnya dibangun, jadi tidak bisa dihancurkan dengan aman. Konstruktor harus memiliki blok percobaan yang diperlukan untuk memastikan bahwa pembersihan yang diperlukan dilakukan sebelum pengecualian dilakukan. Setelah pengecualian berpropagasi di luar ruang lingkup di mana objek dibangun, tidak akan ada panggilan destruktor, karena objek tidak dibangun di tempat pertama.
Pertimbangkan secara khusus konstruktor untuk data anggota di dalam objek yang dihancurkan. Jika salah satu dari itu melempar pengecualian, kode konstruktor utama Anda tidak akan berjalan sama sekali - tetapi beberapa kode yang membentuk bagian implisit dari konstruktor itu akan miliki. Setiap anggota yang telah berhasil dibangun akan secara otomatis dihancurkan. Setiap anggota yang tidak dibangun (termasuk yang melempar pengecualian) tidak.
Jadi pada dasarnya, RAII adalah kebijakan yang memastikan bahwa segala sesuatu yang dibangun sepenuhnya akan dihancurkan tepat waktu, terutama di hadapan lemparan pengecualian, dan bahwa objek apa pun dapat dibangun sepenuhnya atau tidak (tidak ada setengah membangun objek yang Anda tidak bisa tahu cara membersihkan dengan aman). Sumber daya yang dialokasikan juga dibebaskan. Dan banyak pekerjaan yang dilakukan secara otomatis, sehingga programmer tidak perlu terlalu khawatir tentang hal itu.
sumber