Apa itu Dependency Injection?
Dependency injection (DI) adalah teknik dalam object-oriented programming (OOP) untuk meningkatkan modularitas dan fleksibilitas kode dengan cara mengurangi ketergantungan langsung antar komponen.
Dalam DI, sebuah object tidak lagi bertanggung jawab untuk membuat atau mencari dependencies (komponen/layanan yang dibutuhkannya untuk beroperasi) secara langsung. Sebaliknya, dependencies ini disediakan dari luar, sering kali oleh sebuah container atau framework.
Dikarenakan class tidak lagi secara langsung menciptakan object yang dibutuhkannya, engineer akan lebih mudah mengganti dependencies ini dengan implementasi lain (seperti mock objects untuk pengujian) tanpa perlu mengubah kode kelas tersebut.
Namun, jika digunakan secara berlebihan, dependency injection dapat menimbulkan masalah manajemen dan kesalahan pada saat runtime.
Dasar-dasar Dependency Injection
Di dependency injection, terdapat client dan server yang saling berinteraksi untuk memastikan class atau modul dalam aplikasi mendapatkan semua yang dibutuhkan untuk beroperasi, tanpa harus secara langsung bergantung pada implementasi spesifik dari dependencies-nya.
Client (penerima dependency)
Client adalah class yang membutuhkan satu atau lebih dependencies untuk berfungsi dengan tepat. Dependencies bisa berupa layanan, seperti logika bisnis, akses data, atau utilitas lainnya.
Client tidak secara langsung membuat dependencies ini, melainkan menerima dari luar, biasanya melalui constructor, setter, atau metode khusus.
Server (penyedia dependency)
Dalam konteks dependency injection, server adalah sumber atau penyedia dari dependencies yang dibutuhkan oleh client. Hal ini bisa berupa class lain, library, atau framework untuk menghasilkan object yang dibutuhkan client.
Server bertanggung jawab untuk membuat dan mengelola lifecycle dari dependencies ini.
Manfaat Dependency Injection
Dikutip dari TechTarget, manfaat utama penggunaan dependency injection adalah sebagai berikut:
- Mengurangi tugas instansiasi: DI mengurangi code module load dalam instansiasi referensi ke sumber daya. Ini memungkinkan dependencies lebih mudah diganti. Dengan membiarkan framework melakukan penciptaan sumber daya, konfigurasi data menjadi terpusat dan pembaruan hanya terjadi di satu tempat.
- Kustomisasi sumber daya: sumber daya yang di-inject dapat disesuaikan melalui file XML di luar source code. Proses ini dapat melakukan perubahan tanpa harus mengkompilasi ulang seluruh basis kode.
- Loose coupling: DI membuat class menjadi kurang tergantung secara langsung satu sama lain (loose coupling). Artinya, perubahan pada satu bagian dari sistem tidak akan berdampak besar pada bagian lain, membuat kode lebih mudah dikelola dan diperbarui.
- Meningkatkan pengelolaan lifecycle: dalam banyak framework yang menggunakan DI, container DI mengelola lifecycle dari dependencies. Dengan kata lain, pembuatan dan penghancuran object bisa diatur lebih efisien, mengurangi risiko kebocoran memori maupun masalah sumber daya lainnya.
- Membuat kode lebih clean dan terorganisasi: karena DI “memaksa” pemisahan antara pembuatan object dan logika bisnis, kode cenderung lebih clean dan terorganisasi. Dengan begitu, kode lebih mudah dibaca dan dipelihara.
- Meningkatkan reusability: dikarenakan class tidak secara langsung bergantung pada implementasi spesifik, class tersebut menjadi lebih reusable. Sebuah class dengan dependencies yang di-inject bisa dipakai dalam berbagai konteks.
FAQ (Frequently Asked Question)
Apa saja jenis-jenis dependency injection?
Berdasarkan referensi dari FreeCodeCamp, ada tiga jenis utama dependency injection:
Constructor injection
Constructor injection adalah ketika dependencies (komponen yang dibutuhkan oleh class lain untuk berfungsi) disuntikkan langsung melalui class constructor.
Constructor adalah metode khusus yang dipanggil saat object baru dibuat. Jadi, pada saat membuat object, engineer harus menyediakan semua dependencies yang diperlukan. Ini memastikan object tidak dapat dibuat tanpa memiliki semua yang dibutuhkannya.
Setter injection
Setter injection memungkinkan dependencies disuntikkan melalui metode setter.
Metode setter sendiri adalah fungsi dalam class yang dipakai untuk mengatur nilai dari variabel. Berbeda dengan constructor injection, setter injection tidak memaksa untuk menyediakan dependencies saat membuat object. Engineer bisa membuat object terlebih dahulu, lalu menggunakan metode setter untuk menambahkan dependencies kapan pun setelah object dibuat.
Interface injection
Interface injection menggunakan interface untuk menyuntikkan dependencies.
Dalam hal ini, class yang membutuhkan dependency harus mengimplementasikan sebuah interface yang memiliki metode untuk menerima dependency tersebut. Saat metode ini dipanggil, dependency disuntikkan ke dalam class. Artinya, class tersebut secara eksplisit harus menyatakan ia membutuhkan dependency tertentu melalui implementasi interface.