Mengingat konstruktor yang tidak akan pernah, harus menggunakan implementasi berbeda dari beberapa objek yang diinisialisasi, apakah masih praktis untuk menggunakan DI? Bagaimanapun, kita mungkin masih ingin unit test.
Kelas yang bersangkutan menginisialisasi beberapa kelas lain di konstruktornya dan kelas yang digunakannya cukup spesifik. Itu tidak akan pernah menggunakan implementasi lain. Apakah kita dibenarkan untuk menghindari mencoba memprogram ke antarmuka?
Jawaban:
Itu tergantung pada seberapa yakin Anda bahwa "tidak pernah," benar (selama aplikasi Anda akan digunakan).
Secara umum:
sumber
Sementara keuntungan dari pengkodean terhadap antarmuka cukup jelas, Anda harus bertanya pada diri sendiri apa sebenarnya yang didapat dengan tidak melakukannya.
Pertanyaan selanjutnya adalah: apakah bagian dari tanggung jawab kelas yang bersangkutan untuk memilih implementasi atau tidak? Itu mungkin atau mungkin tidak demikian dan Anda harus bertindak sesuai.
Pada akhirnya, selalu ada potensi untuk kendala konyol yang muncul tiba-tiba. Anda mungkin ingin menjalankan bagian kode yang sama secara bersamaan, dan kemungkinan menyuntikkan implementasi dapat membantu sinkronisasi. Atau setelah membuat profil aplikasi Anda, Anda mungkin menemukan Anda menginginkan strategi alokasi yang berbeda dari instantiasi biasa. Atau masalah lintas sektoral muncul dan Anda tidak memiliki dukungan AOP. Siapa tahu?
YAGNI menyarankan bahwa ketika menulis kode, penting untuk tidak menambahkan sesuatu yang berlebihan. Salah satu hal yang cenderung ditambahkan oleh programmer ke kode mereka tanpa menyadarinya, adalah asumsi yang berlebihan. Seperti "metode ini mungkin berguna" atau "ini tidak akan pernah berubah". Keduanya menambah kekacauan pada desain Anda.
sumber
Itu tergantung pada berbagai parameter tetapi berikut adalah beberapa alasan mengapa Anda masih ingin menggunakan DI:
Intinya: Anda mungkin dapat hidup tanpa DI dalam kasus itu tetapi ada kemungkinan bahwa menggunakan DI akan berakhir dengan kode yang lebih bersih.
sumber
Ketika Anda merancang suatu program atau fitur, bagian dari proses berpikir harus bagaimana Anda akan mengujinya. Ketergantungan Injeksi adalah salah satu alat pengujian, dan harus dianggap sebagai bagian dari campuran.
Manfaat tambahan dari Dependency Injection dan menggunakan antarmuka, bukan kelas juga bermanfaat ketika aplikasi diperluas, tetapi mereka juga dapat dipasang kembali ke kode sumber nanti dengan mudah dan aman menggunakan pencarian dan penggantian. - bahkan pada proyek yang sangat besar.
sumber
Banyak jawaban untuk pertanyaan ini dapat diperdebatkan sebagai "Anda mungkin membutuhkannya karena .." sebagai YAGNI jika Anda tidak ingin melakukan unittesting.
Jika Anda menanyakan alasan apa di samping unittests, Anda perlu memprogram ke antarmuka
Ya , Ketergantungan Injeksi sepadan di luar UnitTesting jika Anda memerlukan inversi kontrol . Sebagai contoh jika satu implementasi modul memerlukan modul lain yang tidak dapat diakses di lapisannya.
Contoh: jika Anda memiliki modul
gui
=>businesslayer
=>driver
=>common
.Dalam skenario ini
businesslayer
bisa digunakandriver
tetapidriver
tidak bisa digunakanbusinesslayer
.Jika
driver
membutuhkan fungsionalitas tingkat yang lebih tinggi, Anda dapat mengimplementasikan fungsi ini dibusinesslayer
mana mengimplementasikan antarmuka dalamcommon
lapisan.driver
hanya perlu tahu antarmuka dicommon
lapisan.sumber
Ya, Anda - pertama, lupakan pengujian unit sebagai alasan untuk mendesain kode Anda di sekitar alat uji unit, itu tidak pernah merupakan ide yang baik untuk membengkokkan desain kode Anda agar sesuai dengan kendala buatan. Jika alat Anda memaksa Anda untuk melakukan ini, dapatkan alat yang lebih baik (mis. Microsoft Fakes / Moles yang memungkinkan Anda lebih banyak opsi untuk membuat objek tiruan).
Misalnya, apakah Anda akan membagi kelas menjadi hanya metode publik hanya karena alat uji tidak bekerja dengan metode pribadi? (Saya tahu kebijaksanaan yang berlaku adalah berpura-pura Anda tidak perlu menguji metode pribadi, tapi saya merasa ini adalah reaksi terhadap kesulitan dalam melakukannya dengan alat saat ini, bukan reaksi tulus untuk tidak perlu menguji privat).,
Semua dalam semua itu datang ke apa jenis TDDer Anda - "mockist" seperti Fowler menggambarkan mereka, perlu mengubah kode sesuai dengan alat yang mereka gunakan, sedangkan "klasik" penguji membuat tes yang lebih terintegrasi di alam (Yaitu menguji kelas sebagai satu unit, bukan masing-masing metode) sehingga ada sedikit kebutuhan untuk antarmuka, terutama jika Anda menggunakan alat yang dapat mengejek kelas beton.
sumber
Dependency Injection juga membuat jelas bahwa objek Anda HAS dependensi.
Ketika orang lain pergi menggunakan objek Anda secara naif (tanpa melihat konstruktor), mereka akan menemukan bahwa mereka perlu mengatur layanan, koneksi, dll. Itu tidak jelas karena mereka tidak harus menyerahkannya ke konstruktor . Melewati dependensi membuatnya lebih jelas apa yang dibutuhkan.
Anda juga berpotensi menyembunyikan fakta bahwa kelas Anda mungkin melanggar SRP. Jika Anda melewati banyak dependensi (lebih dari 3), kelas Anda mungkin melakukan terlalu banyak dan harus di-refactored. Tetapi jika Anda membuatnya di konstruktor, kode bau ini akan disembunyikan.
sumber
Saya setuju dengan kedua kubu di sini dan masalah ini masih terbuka untuk diperdebatkan menurut pendapat saya. YAGNI menuntut saya untuk tidak mengubah kode saya agar sesuai dengan anggapan. Unit testing bukan masalah di sini karena saya sangat percaya bahwa ketergantungan tidak akan pernah berubah. Tetapi jika saya adalah Unit testing yang dimaksudkan untuk memulai, saya tidak akan pernah mencapai titik ini pula. Karena saya akhirnya akan berhasil masuk ke DI.
Izinkan saya menawarkan alternatif lain untuk skenario saya secara khusus
Dengan pola pabrik saya dapat melokalkan ketergantungan di satu tempat. Saat menguji saya bisa mengubah implementasi berdasarkan konteks, dan itu cukup bagus. Ini tidak bertentangan dengan YAGNI karena manfaat dari abstrak beberapa konstruksi kelas.
sumber