Satu-satunya anti-pola ketergantungan injeksi sah yang saya ketahui adalah pola Service Locator , yang merupakan anti-pola ketika kerangka DI digunakan untuk itu.
Semua yang disebut DI anti-pola yang pernah saya dengar, di sini atau di tempat lain, hanya sedikit lebih spesifik dari kasus anti-pola desain OO / perangkat lunak umum. Contohnya:
Konstruktor over-injeksi merupakan pelanggaran terhadap Prinsip Tanggung Jawab Tunggal . Terlalu banyak argumen konstruktor menunjukkan terlalu banyak ketergantungan; terlalu banyak dependensi menunjukkan bahwa kelas berusaha melakukan terlalu banyak. Biasanya kesalahan ini berkorelasi dengan bau kode lain, seperti nama kelas yang panjangnya tidak pasti atau ambigu ("manajer"). Alat analisis statis dapat dengan mudah mendeteksi kopling aferen / eferen yang berlebihan.
Injeksi data, sebagai lawan dari perilaku, adalah subtipe dari poltergeist anti-pattern, dengan geist dalam hal ini adalah wadah. Jika suatu kelas perlu mengetahui tanggal dan waktu saat ini, Anda tidak menyuntikkan DateTime
, yang merupakan data; sebagai gantinya, Anda menyuntikkan abstraksi pada jam sistem (saya biasanya menyebut milik saya ISystemClock
, meskipun saya pikir ada yang lebih umum dalam proyek SystemWrappers ). Ini tidak hanya benar untuk DI; itu sangat penting untuk testabilitas, sehingga Anda dapat menguji fungsi yang bervariasi waktu tanpa harus benar-benar menunggu mereka.
Mendeklarasikan setiap siklus hidup sebagai Singleton, bagi saya, adalah contoh sempurna dari pemrograman pemujaan kargo dan pada tingkat yang lebih rendah disebut " objek pembuangan limbah " yang secara bahasa sehari-hari disebut . Saya telah melihat lebih banyak penyalahgunaan tunggal daripada yang saya ingat, dan sangat sedikit yang melibatkan DI.
Kesalahan umum lainnya adalah tipe antarmuka khusus implementasi (dengan nama yang aneh seperti IOracleRepository
) dilakukan hanya untuk dapat mendaftarkannya dalam wadah. Ini dengan sendirinya merupakan pelanggaran terhadap Prinsip Ketergantungan Inversi (hanya karena itu merupakan antarmuka, tidak berarti itu benar-benar abstrak) dan sering juga termasuk antarmuka mengasapi yang melanggar Prinsip Segregasi Antarmuka .
Kesalahan terakhir yang biasanya saya lihat adalah "ketergantungan opsional", yang mereka lakukan di NerdDinner . Dengan kata lain, ada sebuah konstruktor yang menerima injeksi ketergantungan, tetapi juga yang lain konstruktor yang menggunakan "default" implementasi. Ini juga melanggar DIP dan cenderung mengarah pada pelanggaran LSP juga, sebagai pengembang, seiring waktu, mulai membuat asumsi di sekitar implementasi default, dan / atau memulai instance yang baru menggunakan konstruktor default.
Seperti pepatah lama, Anda dapat menulis FORTRAN dalam bahasa apa pun . Dependency Injection bukan peluru perak yang akan mencegah pengembang dari mengacaukan manajemen ketergantungan mereka, tetapi tidak mencegah sejumlah kesalahan umum / anti-pola:
...dan seterusnya.
Jelas Anda tidak ingin merancang kerangka kerja untuk bergantung pada implementasi wadah IoC tertentu , seperti Unity atau AutoFac. Itu, sekali lagi, melanggar DIP. Tetapi jika Anda menemukan diri Anda berpikir untuk melakukan sesuatu seperti itu, maka Anda pasti telah membuat beberapa kesalahan desain, karena Dependency Injection adalah teknik manajemen ketergantungan tujuan umum dan tidak terikat dengan konsep wadah IoC.
Apa pun dapat membangun pohon ketergantungan; mungkin itu wadah IoC, mungkin itu adalah unit test dengan sekelompok ejekan, mungkin itu adalah driver tes yang memasok data dummy. Kerangka kerja Anda seharusnya tidak peduli, dan sebagian besar kerangka kerja yang saya lihat tidak peduli, tetapi mereka masih menggunakan injeksi ketergantungan secara berat sehingga dapat dengan mudah diintegrasikan ke dalam wadah pilihan pengguna akhir IoC.
DI bukan ilmu roket. Cobalah untuk menghindari new
dan static
kecuali ketika ada alasan kuat untuk menggunakannya, seperti metode utilitas yang tidak memiliki dependensi eksternal, atau kelas utilitas yang tidak mungkin memiliki tujuan di luar kerangka kerja (pembungkus interop dan kunci kamus adalah contoh umum dari ini).
Banyak masalah dengan kerangka kerja IoC muncul ketika pengembang pertama kali belajar bagaimana menggunakannya, dan bukannya benar-benar mengubah cara mereka menangani dependensi dan abstraksi agar sesuai dengan model IoC, alih-alih mencoba untuk memanipulasi wadah IoC untuk memenuhi harapan mereka. gaya pengkodean lama, yang sering melibatkan kopling tinggi dan kohesi rendah. Kode buruk adalah kode yang buruk, apakah menggunakan teknik DI atau tidak.