Apa manfaat menggunakan Dependency Injection dan IoC Containers?

62

Saya berencana untuk melakukan pembicaraan tentang Injeksi Ketergantungan dan Kontainer IoC, dan saya sedang mencari beberapa argumen yang baik untuk menggunakannya.

Apa manfaat paling penting dari penggunaan teknik ini, dan alat-alat ini?

Andy Lowry
sumber
1
Lihat di sini dan di sini untuk jawaban StackOverflow dan di sini untuk artikel lengkap yang bagus tentang IoC. Dan jika Anda ingin argumen menentangnya untuk perbandingan, pergilah ke sini di SO.
Jesse C. Slicer
14
bukan menjadi pantat ... tetapi jika Anda tidak tahu mengapa DI / IOC harus digunakan, mengapa Anda membicarakannya? kalah taruhan? ;-)
Steven A. Lowe
2
@ Seven, bosnya mungkin memintanya untuk melakukannya.
1
@ Seven, saya sudah menggunakan DI sepanjang waktu (beberapa akan mengatakan terlalu sering :-D), saya hanya mencari beberapa argumen yang bagus untuk membuat orang lain menggunakannya.
Andy Lowry
2
Orang jarang berbicara tentang penggunaan DI secara berlebihan . Jika Anda menunda setiap keputusan, Anda akan membuat OO yang setara dengan kode spaghetti. Memiliki desain yang koheren mengharuskan, pada titik tertentu, keputusan nyata dibuat.
Macneil

Jawaban:

47

Yang paling penting, bagi saya, membuatnya mudah untuk mengikuti Prinsip Tanggung Jawab Tunggal .

DI / IoC membuatnya mudah bagi saya untuk mengelola dependensi antar objek. Pada gilirannya, itu membuatnya lebih mudah bagi saya untuk memecah fungsionalitas yang koheren ke dalam kontrak sendiri (antarmuka) Akibatnya, kode saya jauh lebih termodulasi sejak saya mengetahui DI / IoC.

Hasil lain dari ini adalah bahwa saya dapat lebih mudah melihat jalan saya ke desain yang mendukung Prinsip Terbuka-Tertutup . Ini adalah salah satu teknik yang paling menginspirasi kepercayaan diri (hanya setelah pengujian otomatis). Saya ragu saya bisa mendukung nilai-nilai dari Prinsip Terbuka-Tertutup.

DI / IoC adalah salah satu dari beberapa hal dalam karier pemrograman saya yang telah menjadi "pengubah permainan". Ada perbedaan besar dalam kualitas antara kode yang saya tulis sebelum & setelah belajar DI / IoC. Biarkan saya menekankan itu lagi. Peningkatan besar dalam kualitas kode.

quentin-starin
sumber
3
Mengapa Prinsip Terbuka-Tutup merupakan masalah besar? Jika Anda merasa perlu mengubah API / antarmuka, mengapa tidak?
Arne Evertsson
@ArneEvertsson Dengarkan Robert C. Martin berbicara tentang Prinsip Terbuka-Tertutup. Anda akan tercerahkan.
Alternatex
@AmeEvertsson Open-Closed sangat penting ketika kode Anda diberikan (misalnya sebagai produk komersial) sebagai modul untuk digunakan orang lain, karena itu membuat kode Anda lebih mudah beradaptasi digunakan tanpa mereka kembali kepada Anda untuk mengubahnya
James Ellis-Jones
2
DI tidak membuatnya mudah untuk mengelola dependensi karena itu jauh lebih kompleks daripada hanya menciptakan ketergantungan pada kelas yang konkret. Namun itu memberikan fleksibilitas tetapi kecuali jika Anda melakukan pengujian unit yang 'tepat', fleksibilitas itu seringkali tidak diperlukan. Kedua keunggulan utama yang diuraikan juga berlaku untuk Layanan Locator, yang lebih sederhana.
James Ellis-Jones
1
Saya menurunkan jawaban ini bertahun-tahun yang lalu; berikut adalah beberapa komentar: 1) Dalam praktiknya, penggunaan DI secara luas cenderung bekerja terhadap SRP, karena programmer hanya terus menambahkan metode pada "pengontrol" yang disuntikkan, "layanan", "DAO", dll., alih-alih membuat kelas baru untuk fungsi baru. Ini yang biasanya Anda lihat terjadi di proyek Java dan C # .NET yang menggunakan beberapa kerangka kerja DI atau wadah. 2) Prinsip terbuka-tertutup hanyalah khayalan Bertrand Meyer tentang manfaat warisan kelas (implementasi); jika Anda mencari di 1400+ halaman bukunya, Anda akan melihat apa yang saya maksud - itu benar-benar konyol.
Rogério
9

Contoh-contoh yang benar-benar membuka mata saya adalah melihat bagaimana hal itu memungkinkan untuk dengan mudah menguji benda yang dibuat sedemikian rupa. Sebelum itu, saya kesulitan mencoba mengisolasi objek untuk unit test. Saya sering menulis tes untuk berinteraksi dengan sistem yang jauh lebih besar. Ini sangat sulit karena sistem secara keseluruhan jauh lebih mudah diprediksi dan lebih rentan untuk berubah daripada komponen individu.

Winston Ewert
sumber
3

Keuntungan dari suntikan ketergantungan adalah:

  1. Kode Anda bersih dan lebih mudah dibaca.
  2. Kode digabungkan secara longgar.
  3. Lebih dapat digunakan kembali karena implementasinya dikonfigurasikan dalam file XML, ini dapat digunakan dalam konteks yang berbeda.
  4. Kode dapat dengan mudah diuji dengan implementasi tiruan yang berbeda.
Solaimani SA
sumber
1

Saya pikir manfaat sebenarnya lebih politis daripada teknis. DI hanyalah alternatif dari pola Service Locator , tidak lebih. Dengan sendirinya, itu tidak membuatnya lebih mudah untuk mengikuti prinsip-prinsip seperti SRP atau OCP, atau untuk memisahkan lapisan. Responden lain di sini membingungkan konsep dan teknik yang berbeda, IMO.

Anda dapat mencapai tujuan yang sama sehubungan dengan kohesi tinggi dan kopling rendah dengan menggunakan Layanan Locators, atau dengan hanya instantiating dependensi secara langsung kapan saja berlaku (yang sebagian besar waktu).

Sekarang, saya tahu banyak yang akan tidak setuju dengan pendapat ini. Saya akan senang mendiskusikan contoh-contoh nyata.

Rogério
sumber
2
Tapi secara langsung memanggil pelacak layanan atau instantiating ketergantungan konkret biasanya kabel kabel dependensi Anda, atau setidaknya di mana dependensi Anda berasal. Itu sepertinya mengalahkan tujuan DI. Anda masih harus menyuntikkan pelacak layanan, juga.
Matt H
Menggunakan Service Locator tidak melakukan kabel apa pun kecuali penggunaan kelas Service Locator itu sendiri, yang biasanya tidak "disuntikkan". Instantiating kelas implementasi konkret baik-baik saja dalam kasus di mana Anda tidak memerlukan konfigurasi eksternal (misalnya, programer biasanya instantiate langsung kelas ArrayList alih-alih menggunakan DI - yang akan berlebihan).
Rogério
1
Anda menyebutkan "kopling rendah" dan kemudian Anda mengatakan bahwa pelacak layanan tidak berdampak pada tingkat kopling aplikasi. Hal yang sama untuk instantiator kolaborator langsung pada kode, saya tidak bisa memikirkan cara yang lebih sempurna untuk memasangkan objek dengan dependensinya. Bagaimana Anda unit menguji kedua skenario? Saya, dengan hormat, sepenuhnya tidak setuju dengan semua yang Anda katakan.
Clint Eastwood
@ Jonathan Anda harus membaca artikel yang memperkenalkan DI itu; penulis menyimpulkan dengan mengatakan DI dan ServiceLocator "kira-kira setara", dengan "sedikit keunggulan" untuk yang terakhir. Kopling yang penting adalah antara komponen dan komponen lain yang mungkin memiliki beberapa implementasi; ServiceLocator adalah layanan infrastruktur dengan hanya satu implementasi, jadi tidak apa-apa. Catatan saya menulis "instantiating dependensi kapan pun berlaku "; tentu saja, jika Anda perlu memisahkan konfigurasi dari penggunaan, Anda tidak akan melakukannya.
Rogério
1
@ Jonathan Mengenai pengujian unit, itu adalah mitos bahwa instantiator kolaborator mencegah pembuatan tes semacam itu; ada alat mengejek terkenal yang melakukan pekerjaan mengisolasi kelas dari implementasi dependensi, apakah mereka disuntikkan atau tidak.
Rogério
-1

Ketika DI digunakan untuk mengekspos objek dalam untuk tujuan pengujian, polanya telah disalahgunakan.

thomas-peter
sumber
1
apa yang kamu maksud dengan "objek batin"? dalam OOP nyata (perhatikan bahwa mungkin hanya 1% dari programmer yang tahu apa yang sebenarnya berarti), ada objek yang berkomunikasi satu sama lain dengan cara mengirim pesan (yaitu pemanggilan metode). Dalam pengertian itu, setiap objek harus memiliki satu tanggung jawab tunggal, tidak ada objek "lebih penting" daripada yang lain ... setiap objek memiliki tugas tunggal dan mereka bekerja sama untuk mencapai fungsi yang disediakan oleh keseluruhan sistem. Sangat penting untuk menguji setiap objek secara terpisah sehingga kami tahu kami tidak melewatkan kasus apa pun, itulah yang DI sangat pandai lakukan.
Clint Eastwood
Saya sudah lupa.
thomas-peter