Haruskah penggunaan Injeksi Ketergantungan dan wadah Pembalikan Kontrol menghapus semua kemunculan new
kata kunci " " dari kode Anda?
Dengan kata lain, haruskah setiap objek / ketergantungan, tidak peduli seberapa sederhana atau berumur pendek, "terdaftar" dalam wadah IoC Anda dan disuntikkan ke dalam metode / kelas yang perlu menggunakannya?
Jika tidak, di mana Anda menggambar garis antara mana dependensi / objek didaftarkan di wadah IoC, versus apa yang akan dibuat "in-line" sebagai referensi konkret, melalui new
kata kunci?
.net
dependency-injection
ioc-containers
CraigTP
sumber
sumber
Jawaban:
Hindari dogma. Lakukan apa yang terasa benar.
Saya lebih suka menggunakan "baru" untuk struktur data yang tidak memiliki perilaku.
Jika kelas memang memiliki perilaku, saya kemudian melihat lingkup perilaku itu. Jika stateless dan tidak memiliki dependensi, saya condong ke arah "baru". Saya hanya mulai refactoring ke arah DI ketika saya perlu menambahkan ketergantungan pada sumber daya stateful (seperti database atau file), atau ke kelas lain dengan sumber daya tersebut.
sumber
new
ketergantungan pada kode saya sendiri yang mendorong pertanyaan saya. Itu adalah kelas sederhana tanpa fungsi atau "perilaku" per-se, hanya properti sederhana.Dalam buku saya , saya memberikan perbedaan antara Stabil dan Ketergantungan Volatile . Sangat penting untuk menggunakan DI dengan Volatile Dependencies, tetapi seringkali Anda dapat mencapai kopling yang lebih longgar dengan juga mengabstraksikan dan menyuntikkan Dependensi Stabil.
Perlu diingat bahwa penerapan DI tidak harus bergantung pada suatu wadah DI . Dalam kasus di mana Poor Man's sedang digunakan, tidak ada
new
kata kunci yang dihapus - mereka hanya dipindahkan ke Root Komposisi .Beberapa orang sebenarnya lebih suka DIM Pria Miskin daripada DI Kontainer. Biaya pemeliharaan mungkin lebih tinggi, tetapi Anda mendapatkan keamanan waktu kompilasi sebagai imbalannya. Ketika saya baru-baru ini mendengar Dan North mengatakan: "
new
adalah yang barunew
" :)Apa yang dimaksud dengan ini hanyalah daripada mengimplementasikan Root Komposisi dengan Kontainer DI, itu hanya berisi sejumlah
new
pernyataan bersarang .sumber
"Baru" bukan kata kunci terlarang. Aturan pribadi saya:
Semua "layanan" (Saya menyebut layanan kelas yang dirancang untuk menyediakan satu atau lebih metode yang terkait dengan satu dan hanya satu hal; misalnya: mengakses database, mengambil / memperbarui data yang terkait dengan domain tertentu) terdaftar dalam wadah IOC. Tidak ada kelas yang harus membuat keputusan tentang bagaimana mendapatkan implementasi dari layanan yang diberikan yang perlu digunakan. Oleh karena itu, setiap kali Anda perlu menggunakan layanan yang ada, Anda harus mengkonfigurasi kelas Anda dan wadah IOC untuk menyediakannya kepada Anda. Bayangkan Anda tidak menyadari bagaimana implementasi Anda bekerja, itu bisa berupa layanan web, Anda tidak peduli.
Semua kacang, atau model harus dibuat dengan kata kunci "baru" atau dengan pabrik terdaftar IOC ketika saya membutuhkannya agar beberapa properti default diaktifkan. Ada juga kasus khusus dari kelas utilitas yang hanya berisi metode statis (misalnya: layanan utilitas matematika). Jika mereka benar-benar mandiri dan tidak memerlukan koneksi database atau layanan terdaftar-IOC lain, saya meninggalkan mereka keluar dari IOC dan mereka akan dipanggil secara statis. Namun, jika satu kelas seperti itu perlu menggunakan layanan terdaftar-IOC yang ada, saya mengubahnya ke kelas tunggal dan mendaftarkannya di IOC.
sumber
Saya hanya ingin menambahkan jawaban yang ada yang dibesarkan sebelumnya,
new
sangat baik untuk membuat objek yang merupakan objek bernilai murni (yaitu hanya memiliki properti / getter / setter). Lihat Blog Pengujian Google untuk lebih detail.sumber
new
'edJelas tergantung pada bahasa yang Anda gunakan. Jika bahasa Anda memaksa Anda untuk menggunakan objek untuk mewakili objek dan catatan aktual (nilai objek, struct), maka jawabannya kemungkinan besar tidak.
Berbicara murni tentang objek "nyata", tidak ada yang salah dengan membuat instance secara eksplisit. Apa yang harus Anda ingat adalah bahwa semua kelas harus mengikuti prinsip tanggung jawab tunggal. Seharusnya tidak menjadi tanggung jawab kelas untuk memilih pelaksana layanan yang diandalkannya. Namun ada kelas yang memiliki tanggung jawab itu, yaitu untuk menyediakan pelaksana layanan tertentu. Sebuah IoC mungkin kelas seperti itu. Sebenarnya semua jenis pabrik adalah kelas seperti itu.
Jadi untuk meringkas: Hanya kelas-kelas tersebut yang harus secara langsung instantiate objek, siapa yang bertanggung jawab untuk memilih kelas mana yang akan dipakai.
Anda mungkin menemukan kriteria ini bermanfaat: http://en.wikipedia.org/wiki/GRASP_(object-oriented_design)#Creator
sumber
Satu kata: Tidak.
Lebih banyak kata: Ketergantungan injeksi persis seperti itu. Ini adalah cara di mana Anda memperkenalkan sumber daya yang bergantung pada objek lain, tetapi seharusnya tidak mengetahui detail rumit dari, dari sumber lain. Menggunakan DI tidak berarti bahwa TIDAK ADA dalam program Anda harus tahu cara membuat objek lain; pada kenyataannya, saya berpendapat bahwa sangat tidak mungkin untuk program non-sepele untuk menghindari kata kunci "baru" (atau alternatif berbasis refleksi) sepenuhnya. Namun, DI memang berarti bahwa objek yang seharusnya TIDAK HARUS tahu cara membuat objek kompleks yang membutuhkan banyak dependensi yang akan secara ketat memasangkan objek ini dengan yang lain, seharusnya tidak memiliki semua pengetahuan yang berhubungan erat ini.
Saya akan mempelajari dua teori utama desain perangkat lunak O / O, GRASP dan SOLID. GRASP akan memberitahu Anda untuk mempelajari tujuan objek, dan bertanya pada diri sendiri, "Haruskah objek ini bertanggung jawab untuk membuat objek baru dari tipe lain ini? Apakah itu bagian dari 'deskripsi pekerjaan' dari objek ini?" SOLID melangkah lebih jauh: "S" adalah singkatan dari "Prinsip Tanggung Jawab Tunggal", yang menyatakan secara jelas bahwa suatu objek harus memiliki satu pekerjaan, dan itu harus menjadi satu-satunya objek dalam program yang melakukan pekerjaan tertentu itu.
Jadi, GRASP umumnya akan mendorong Anda untuk melihat kelas-kelas Anda yang ada untuk membuat objek baru ini, dan menemukan satu yang sesuai dengan tugas membuat objek ini dengan apa yang sudah dilakukan objek, sambil mempertahankan tingkat "kohesi" yang Anda inginkan. SOLID akan memberi tahu Anda bahwa kohesi adalah kuncinya; tugas membuat benda-benda ini harus diberikan kepada beberapa pabrik yang harus disuntikkan ke kelas Anda. Saya pikir Anda akan menemukan, ketika kompleksitas program Anda terus tumbuh, kepatuhan terhadap salah satu dari metodologi ini, dengan kemauan untuk memperbaiki, akan menghasilkan arsitektur yang sangat mirip.
sumber