Inversion of Control adalah prinsip desain umum dari arsitektur perangkat lunak yang membantu menciptakan kerangka kerja perangkat lunak modular yang dapat digunakan kembali dan mudah dipelihara.
Ini adalah prinsip desain di mana Aliran Kontrol "diterima" dari pustaka yang ditulis secara umum atau kode yang dapat digunakan kembali.
Untuk memahaminya dengan lebih baik, mari kita lihat bagaimana kita dulu membuat kode di hari-hari awal pengkodean kita. Dalam bahasa prosedural / tradisional, logika bisnis umumnya mengontrol aliran aplikasi dan "Memanggil" kode / fungsi generik atau dapat digunakan kembali. Misalnya, dalam aplikasi Konsol sederhana, aliran kontrol saya dikendalikan oleh instruksi program saya, yang mungkin mencakup panggilan ke beberapa fungsi umum yang dapat digunakan kembali.
print ("Please enter your name:");
scan (&name);
print ("Please enter your DOB:");
scan (&dob);
//More print and scan statements
<Do Something Interesting>
//Call a Library function to find the age (common code)
print Age
Berbeda dengan IoC, Frameworks adalah kode yang dapat digunakan kembali yang "Memanggil" logika bisnis.
Misalnya, dalam sistem berbasis windows, kerangka kerja akan tersedia untuk membuat elemen UI seperti tombol, menu, jendela, dan kotak dialog. Ketika saya menulis logika bisnis aplikasi saya, itu akan menjadi peristiwa kerangka kerja yang akan memanggil kode logika bisnis saya (ketika sebuah peristiwa dipecat) dan BUKAN sebaliknya.
Meskipun, kode framework tidak mengetahui logika bisnis saya, ia masih akan mengetahui cara memanggil kode saya. Ini dicapai dengan menggunakan acara / delegasi, callback, dll. Di sini, Kontrol aliran "Dibalik".
Jadi, alih-alih bergantung pada aliran kontrol pada objek yang terikat secara statis, aliran bergantung pada grafik objek secara keseluruhan dan hubungan antara objek yang berbeda.
Dependency Injection adalah pola desain yang mengimplementasikan prinsip IoC untuk menyelesaikan dependensi objek.
Dengan kata sederhana, saat Anda mencoba menulis kode, Anda akan membuat dan menggunakan kelas yang berbeda. Satu kelas (Kelas A) dapat menggunakan kelas lain (Kelas B dan / atau D). Jadi, Kelas B dan D adalah dependensi kelas A.
Sebuah analogi sederhana akan menjadi mobil kelas. Sebuah mobil mungkin bergantung pada kelas lain seperti Mesin, Ban, dan lainnya.
Dependency Injection menyarankan bahwa alih-alih class Dependent (Class Car di sini) membuat dependensinya (Class Engine dan class Tire), class harus diinjeksi dengan instance konkret dari dependensi.
Mari kita pahami dengan contoh yang lebih praktis. Pertimbangkan bahwa Anda sedang menulis TextEditor Anda sendiri. Antara lain, Anda dapat memiliki pemeriksa ejaan yang menyediakan fasilitas bagi pengguna untuk memeriksa kesalahan ketik dalam teksnya. Implementasi sederhana dari kode semacam itu dapat berupa:
Class TextEditor
{
//Lot of rocket science to create the Editor goes here
EnglishSpellChecker objSpellCheck;
String text;
public void TextEditor()
{
objSpellCheck = new EnglishSpellChecker();
}
public ArrayList <typos> CheckSpellings()
{
//return Typos;
}
}
Pada pandangan pertama, semuanya tampak cerah. Pengguna akan menulis beberapa teks. Pengembang akan menangkap teks dan memanggil fungsi CheckSpellings dan akan menemukan daftar kesalahan ketik yang akan dia tunjukkan kepada Pengguna.
Semuanya tampaknya bekerja dengan baik hingga suatu hari ketika seorang pengguna mulai menulis bahasa Prancis di Editor.
Untuk memberikan dukungan untuk lebih banyak bahasa, kita perlu memiliki lebih banyak Pemeriksa Ejaan. Mungkin Prancis, Jerman, Spanyol, dll.
Di sini, kami telah membuat kode yang digabungkan erat dengan "Inggris" SpellChecker yang digabungkan erat dengan kelas TextEditor kami, yang berarti kelas TextEditor kami bergantung pada EnglishSpellChecker atau dengan kata lain EnglishSpellCheker adalah ketergantungan untuk TextEditor. Kami perlu menghapus ketergantungan ini. Lebih lanjut, Editor Teks Kami membutuhkan cara untuk menyimpan referensi konkret dari Pemeriksa Ejaan apa pun berdasarkan kebijaksanaan pengembang pada waktu proses.
Jadi, seperti yang kita lihat dalam pengenalan DI, itu menyarankan bahwa kelas harus diinjeksi dengan dependensinya. Jadi, itu harus menjadi tanggung jawab kode panggilan untuk memasukkan semua dependensi ke kelas / kode yang dipanggil. Jadi kita bisa merestrukturisasi kode kita sebagai
interface ISpellChecker
{
Arraylist<typos> CheckSpelling(string Text);
}
Class EnglishSpellChecker : ISpellChecker
{
public override Arraylist<typos> CheckSpelling(string Text)
{
//All Magic goes here.
}
}
Class FrenchSpellChecker : ISpellChecker
{
public override Arraylist<typos> CheckSpelling(string Text)
{
//All Magic goes here.
}
}
Dalam contoh kita, kelas TextEditor harus menerima contoh konkret dari tipe ISpellChecker.
Sekarang, ketergantungan dapat disuntikkan ke Pembuat, Properti Publik, atau metode.
Mari kita coba mengubah kelas kita menggunakan Constructor DI. Kelas TextEditor yang diubah akan terlihat seperti ini:
Class TextEditor
{
ISpellChecker objSpellChecker;
string Text;
public void TextEditor(ISpellChecker objSC)
{
objSpellChecker = objSC;
}
public ArrayList <typos> CheckSpellings()
{
return objSpellChecker.CheckSpelling();
}
}
Sehingga kode panggilan, saat membuat editor teks dapat memasukkan Jenis Pemeriksa Ejaan yang sesuai ke instance TextEditor.
Anda dapat membaca artikel lengkapnya di sini