Inversion of Control adalah prinsip desain generik arsitektur perangkat lunak yang membantu menciptakan kerangka kerja perangkat lunak modular yang dapat digunakan kembali dan mudah dipelihara.
Ini adalah prinsip desain di mana Flow of Control "diterima" dari perpustakaan yang ditulis secara umum atau kode yang dapat digunakan kembali.
Untuk memahaminya dengan lebih baik, mari kita lihat bagaimana kita menggunakan kode pada hari-hari awal pengkodean kita. Dalam bahasa prosedural / tradisional, logika bisnis umumnya mengontrol aliran aplikasi dan "Memanggil" kode / fungsi umum atau yang dapat digunakan kembali. Misalnya, dalam aplikasi Konsol sederhana, aliran kendali saya dikendalikan oleh instruksi program saya, yang dapat 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
Dalam Kontras, dengan IoC, Kerangka adalah kode yang dapat digunakan kembali yang "Memanggil" logika bisnis.
Misalnya, dalam sistem berbasis windows, kerangka kerja sudah tersedia untuk membuat elemen UI seperti tombol, menu, jendela dan kotak dialog. Ketika saya menulis logika bisnis dari aplikasi saya, itu akan menjadi peristiwa kerangka kerja yang akan memanggil kode logika bisnis saya (ketika suatu peristiwa dipecat) dan BUKAN sebaliknya.
Meskipun, kode kerangka kerja ini tidak mengetahui logika bisnis saya, masih akan tahu cara memanggil kode saya. Ini dicapai dengan menggunakan acara / delegasi, panggilan balik dll. Di sini Kontrol aliran adalah "Terbalik".
Jadi, alih-alih bergantung pada aliran kontrol pada objek yang terikat secara statis, aliran tersebut bergantung pada grafik objek keseluruhan dan hubungan antara objek yang berbeda.
Dependency Injection adalah pola desain yang menerapkan prinsip IoC untuk menyelesaikan dependensi objek.
Dengan kata sederhana, ketika 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.
Analogi sederhana akan menjadi Mobil kelas. Mobil mungkin bergantung pada kelas lain seperti Engine, Ban, dan lainnya.
Ketergantungan Injeksi menunjukkan bahwa alih-alih kelas Ketergantungan (Kelas Mobil di sini) menciptakan dependensinya (Kelas Mesin dan kelas Ban), kelas harus disuntikkan dengan contoh konkret ketergantungan.
Mari kita pahami dengan contoh yang lebih praktis. Pertimbangkan bahwa Anda sedang menulis TextEditor Anda sendiri. Antara lain, Anda bisa memiliki pemeriksa ejaan yang menyediakan fasilitas kepada pengguna untuk memeriksa kesalahan ketik dalam teksnya. Implementasi sederhana dari kode semacam itu dapat:
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, semua tampak kemerahan. Pengguna akan menulis beberapa teks. Pengembang akan menangkap teks dan memanggil fungsi CheckSpellings dan akan menemukan daftar Typos yang akan ditampilkan kepada Pengguna.
Segalanya tampak bekerja dengan baik sampai 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 Perancis, Jerman, Spanyol dll.
Di sini, kami telah membuat kode yang dipasangkan dengan SpellChecker "Bahasa Inggris" yang dipasangkan dengan kelas TextEditor kami, yang berarti kelas TextEditor kami bergantung pada EnglishSpellChecker atau dengan kata lain EnglishSpellCheker adalah ketergantungan untuk TextEditor. Kami harus menghapus ketergantungan ini. Lebih lanjut, Editor Teks kami membutuhkan cara untuk menyimpan referensi konkret dari Pemeriksa Ejaan apa pun berdasarkan kebijaksanaan pengembang pada waktu berjalan.
Jadi, seperti yang kita lihat dalam pengenalan DI, ini menunjukkan bahwa kelas harus disuntikkan dengan dependensinya. Jadi, itu harus menjadi tanggung jawab kode panggilan untuk menyuntikkan semua dependensi ke kelas / kode yang dipanggil. Jadi kami dapat menyusun kembali kode kami 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 kami, kelas TextEditor harus menerima contoh konkret dari tipe ISpellChecker.
Sekarang, ketergantungan dapat disuntikkan di Konstruktor, Properti Publik atau metode.
Mari kita coba mengubah kelas kita menggunakan Constructor DI. Kelas TextEditor yang diubah akan terlihat seperti:
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 menyuntikkan SpellChecker Type yang sesuai ke instance dari TextEditor.
Anda dapat membaca artikel selengkapnya di sini