Apa itu Dependency Injection dan Inversion of Control dalam Spring Framework?


112

"Dependency Injection" dan "Inversion of Control" sering disebut sebagai keuntungan utama menggunakan framework Spring untuk mengembangkan framework Web

Adakah yang bisa menjelaskan apa itu dalam istilah yang sangat sederhana dengan contoh jika memungkinkan?



3
@SteveChambers itu bukan duplikat, pertanyaan ini ditanyakan di Springs Perspective. Pertanyaan itu dalam perspektif umum.
VdeX

Jawaban:


233
  • Spring membantu dalam pembuatan aplikasi yang digabungkan secara longgar karena Injeksi Ketergantungan .
  • Di Spring, objek mendefinisikan asosiasinya (dependensi) dan tidak khawatir tentang bagaimana mereka akan mendapatkan dependensi tersebut . Merupakan tanggung jawab Spring untuk menyediakan dependensi yang diperlukan untuk membuat objek.

Sebagai contoh : Misalkan kita memiliki sebuah objek Employeedan memiliki ketergantungan pada objek Address. Kami akan mendefinisikan kacang yang sesuai dengan Employeeyang akan menentukan ketergantungannya pada objek Address.

Ketika Spring mencoba membuat sebuah Employeeobjek, ia akan melihat yang Employeememiliki ketergantungan Address, jadi pertama akan membuat Addressobjek (objek dependen) dan kemudian menyuntikkannya ke dalam Employeeobjek.

  • Inversion of Control ( IoC ) dan Dependency Injection ( DI ) digunakan secara bergantian. IoC dicapai melalui DI. DI adalah proses penyediaan dependensi dan IoC adalah hasil akhir dari DI. ( Catatan: DI bukan satu-satunya cara untuk mencapai IoC. Ada cara lain juga.)

  • Oleh DI, tanggung jawab untuk membuat objek dialihkan dari kode aplikasi kita ke container Spring; fenomena ini disebut IoC.

  • Injeksi Ketergantungan dapat dilakukan dengan injeksi penyetel atau injeksi konstruktor.

Saya tidak setuju. Saya rasa ini bukan penjelasan yang jelas. Mengapa Anda tidak bisa memberi contoh "Alamat" di dalam "Karyawan" alih-alih mendapatkan kerangka kerja untuk membuat dan menyuntikkannya? Contoh yang sedikit lebih rinci diperlukan.
Boris

2
@Boris Tidak ada yang mengatakan Anda tidak dapat membuat contoh objek Anda sendiri. Tetapi satu-satunya tujuan dari jawabannya adalah untuk menunjukkan bagaimana Anda dapat mencapai hal yang sama dengan DI. Anda dapat memiliki DI dan objek yang dibuat oleh kode klien. Ini masih akan disebut IOC, setidaknya sebagian.
bogdan.rusu


Boris. Sangat cemburu? Itu jawaban terbaik yang pernah ada.
Aniket Kapse

31

Saya akan menuliskan pemahaman sederhana saya tentang dua istilah ini: (Untuk pemahaman cepat, cukup baca contoh)

  • Injeksi Ketergantungan (DI):
    Injeksi ketergantungan umumnya berarti meneruskan objek dependen sebagai parameter ke suatu metode, daripada meminta metode tersebut membuat objek dependen .
    Artinya dalam praktiknya adalah bahwa metode tersebut tidak memiliki ketergantungan langsung pada implementasi tertentu; implementasi apa pun yang memenuhi persyaratan dapat diteruskan sebagai parameter.

    Dengan implementasi ini objek mendefinisikan dependensinya. Dan musim semi membuatnya tersedia.
    Ini mengarah pada pengembangan aplikasi yang digabungkan secara longgar.

    Contoh Singkat: OBYEK KARYAWAN KETIKA DIBUAT, OBYEK AKAN SECARA OTOMATIS MEMBUAT OBYEK ALAMAT (jika alamat didefinisikan sebagai ketergantungan oleh objek Karyawan) *.

  • Inversion of Control (IoC) Container:
    Ini adalah karakteristik umum dari framework, IoC mengelola objek java
    - dari instantiation hingga destruksi melalui BeanFactory.
    - Komponen Java yang dibuat oleh wadah IoC disebut kacang, dan wadah IoC mengelola ruang lingkup kacang, peristiwa siklus hidup, dan fitur AOP yang telah dikonfigurasi dan dikodekan.

    QUICK EXAMPLE:Inversion of Control is about getting freedom, more flexibility, and less dependency. When you are using a desktop computer, you are slaved (or say, controlled). You have to sit before a screen and look at it. Using keyboard to type and using mouse to navigate. And a bad written software can slave you even more. If you replaced your desktop with a laptop, then you somewhat inverted control. You can easily take it and move around. So now you can control where you are with your computer, instead of computer controlling it.

    Dengan menerapkan Inversion of Control, konsumen perangkat lunak / objek mendapatkan lebih banyak kontrol / opsi atas perangkat lunak / objek, daripada dikontrol atau memiliki lebih sedikit opsi.

    Inversi kontrol sebagai pedoman desain melayani tujuan berikut:
    - Ada pemisahan pelaksanaan tugas tertentu dari implementasi.
    - Setiap modul dapat fokus pada apa yang dirancang untuk itu.
    - Modul tidak membuat asumsi tentang apa yang dilakukan sistem lain tetapi bergantung pada kontrak mereka.
    - Mengganti modul tidak memiliki efek samping pada modul lain

Saya akan membuat hal-hal abstrak di sini, Anda dapat mengunjungi tautan berikut untuk pemahaman detail tentang topik tersebut.

Bacaan yang bagus dengan contoh

Penjelasan detail


11

Dalam Spring Objects digabungkan secara longgar yaitu, setiap kelas tidak tergantung satu sama lain sehingga semuanya dapat diuji secara individual. Tapi saat menggunakan kelas-kelas itu, sebuah kelas mungkin bergantung pada kelas lain yang perlu dibuat instance-nya terlebih dahulu.

Jadi, kami memberi tahu spring bahwa kelas A bergantung pada kelas B. Jadi, saat membuat kacang (seperti kelas) untuk kelas A, ia membuat instance kelas B sebelum kelas A dan menyuntikkannya di kelas A menggunakan metode penyetel atau konstruktor DI. Yaitu, kami memberi tahu musim semi ketergantungan pada run-time. Ini DI.

Karena, kami menetapkan tanggung jawab untuk membuat objek (kacang), mempertahankannya dan agregatnya ke Spring alih-alih melakukan hard-coding, kami menyebutnya Inversion Of Control (IOC).


7

Inversion Of Control (IOC):

IoC adalah pola desain yang mendeskripsikan pembalikan aliran kontrol dalam suatu sistem, sehingga aliran eksekusi tidak dikendalikan oleh bagian pusat kode. Ini berarti bahwa komponen hanya boleh bergantung pada abstraksi komponen lain dan tidak bertanggung jawab untuk menangani pembuatan objek dependen. Sebagai gantinya, instance objek disuplai saat runtime oleh kontainer IoC melalui Dependency Injection (DI).

IoC memungkinkan desain perangkat lunak yang lebih baik yang memfasilitasi penggunaan kembali, sambungan longgar, dan pengujian komponen perangkat lunak yang mudah.

Dependency Injection (DI):

DI adalah teknik untuk meneruskan dependensi ke konstruktor objek. Jika objek telah dimuat dari penampung, maka dependensinya akan otomatis dipasok oleh penampung. Ini memungkinkan Anda menggunakan dependensi tanpa harus membuat instance secara manual. Ini mengurangi kopling dan memberi Anda kontrol yang lebih besar atas masa pakai instance objek.

klik untuk melihat lebih banyak


6

Spring: Spring adalah container "Inversion of Control" untuk Platform Java.

Inversion of Control (IoC): Inversion of Control (IoC) adalah praktik pemrograman berorientasi objek di mana penggandengan objek dibatasi pada waktu proses oleh objek "assembler" dan biasanya tidak dapat diketahui pada waktu kompilasi menggunakan analisis statis.

Dependency Injection (DI): "Dependency injection adalah pola desain perangkat lunak yang memungkinkan penghapusan dependensi hard-code dan memungkinkan untuk mengubahnya, baik pada saat run-time atau compile-time." -wiki.


Bagaimana ini bisa lebih sederhana dari apa yang sudah ada (dari mana jawaban ini bersumber)? Itu tidak memperhitungkan permintaan OP untuk kesederhanaan, kecuali kutipan ganda di sekitar terminologi secara ajaib membuat segalanya lebih sederhana.
Nyala udun

6

Pembalikan kontrol- Ini berarti memberikan kontrol untuk membuat dan membuat instance kacang pegas ke wadah Spring IOC dan satu-satunya pekerjaan yang dilakukan pengembang adalah mengkonfigurasi kacang dalam file xml musim semi.

Injeksi ketergantungan-

Pertimbangkan kelas Karyawan

class Employee { 
   private int id;
   private String name;
   private Address address;

   Employee() {
     id = 10;
     name="name";
     address = new Address();
   }


}

dan pertimbangkan Alamat kelas

class Address {
   private String street;
   private String city;

   Address() {
     street="test";
     city="test1";

  }
}

Pada kode di atas, nilai kelas alamat hanya akan diset ketika kelas Karyawan dibuat, yang merupakan ketergantungan kelas Alamat pada kelas Karyawan. Dan pegas memecahkan masalah ini menggunakan konsep Injeksi Ketergantungan dengan menyediakan dua cara untuk menyuntikkan ketergantungan ini.

  1. Injeksi penyetel

Metode penyetel dalam kelas Karyawan yang mengambil referensi dari kelas Alamat

public void setAddress(Address addr) {
    this.address = addr;
}
  1. Injeksi konstruktor

Konstruktor di kelas Karyawan yang menerima Alamat

Employee(Address addr) {
      this.address = addr;
}

Dengan cara ini, nilai kelas Alamat dapat disetel secara independen menggunakan injeksi penyetel / konstruktor.


3

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


1

Cara tradisional untuk mendapatkan instance alamat di Employee adalah dengan membuat instance baru dari kelas Address. Spring membuat semua objek dependen untuk kita sehingga kita tidak perlu khawatir tentang objek.

Jadi di Spring kita hanya bergantung pada wadah pegas yang memberi kita objek ketergantungan.


1

IOC adalah teknik di mana Anda membiarkan orang lain membuat objek untuk Anda. Dan orang lain dalam kasus pegas adalah wadah IOC.

Injeksi Ketergantungan adalah teknik di mana satu objek memasok ketergantungan objek lain.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.