Haruskah penggunaan DI / IoC menghapus semua kemunculan kata kunci "baru"?

21

Haruskah penggunaan Injeksi Ketergantungan dan wadah Pembalikan Kontrol menghapus semua kemunculan newkata 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 newkata kunci?

CraigTP
sumber
Saya memiliki pemikiran yang sama, di sepanjang baris "apakah 'baru' kata 4 huruf?"
Michael Easter

Jawaban:

27

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.

Alex Beynenson
sumber
15
+1 untuk "menghindari dogma". Terlalu mudah untuk jatuh ke dalam perangkap hanya mengikuti gerakan tanpa memahami apa yang terjadi atau di mana harus digunakan dengan benar.
Wayne Molina
@ Alex Saya suka ini. Pendekatan yang sangat pragmatis. Lucunya, saya akan menambahkan beberapa kode dalam pertanyaan saya yang menunjukkan newketergantungan pada kode saya sendiri yang mendorong pertanyaan saya. Itu adalah kelas sederhana tanpa fungsi atau "perilaku" per-se, hanya properti sederhana.
CraigTP
11

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 newkata 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: " newadalah yang baru new" :)

Apa yang dimaksud dengan ini hanyalah daripada mengimplementasikan Root Komposisi dengan Kontainer DI, itu hanya berisi sejumlah newpernyataan bersarang .

Mark Seemann
sumber
Mark, untuk sedikit memperluas komentar Twitter saya , Programmer adalah tempat yang tepat untuk pertanyaan konseptual, papan tulis-y yang tidak berurusan dengan kesalahan spesifik dalam implementasi.
Adam Lear
3
Stack Overflow memiliki 2000+ pertanyaan dalam tag ketergantungan-injeksi, dan banyak dari mereka seperti ini. Pemrogram memiliki 23 pertanyaan dalam tag yang sama. Berdasarkan angka-angka ini, ke mana pengembang harus pergi untuk memiliki peluang terbesar untuk mendapatkan jawaban atas pertanyaan seperti ini?
Mark Seemann
1
Banyak dari pertanyaan-pertanyaan itu mendahului programmer sepenuhnya. Situs ini dibuat untuk menghilangkan pertanyaan konseptual dari SO dan memberi mereka rumah yang khusus. Dan kita masih terus berkembang. Ini adalah pekerjaan yang sedang berjalan, tetapi idealnya pertanyaan yang tidak melibatkan masalah implementasi spesifik akan dimigrasi ke sini. Sementara itu kami melakukan apa yang kami bisa.
Adam Lear
3

"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.

Jalayn
sumber
2

Saya hanya ingin menambahkan jawaban yang ada yang dibesarkan sebelumnya, newsangat baik untuk membuat objek yang merupakan objek bernilai murni (yaitu hanya memiliki properti / getter / setter). Lihat Blog Pengujian Google untuk lebih detail.

Mendongkrak
sumber
+1 untuk tautan. Poin 9 dalam posting blog itu menjawab pertanyaan dan memberikan perbedaan pragmatis antara apa yang seharusnya dan tidak boleh new'ed
CraigTP
1

Jelas 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

back2dos
sumber
1

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.

KeithS
sumber