Dependency injection: Cara menjualnya [ditutup]

95

Perlu diketahui bahwa saya penggemar berat ketergantungan injeksi (DI) dan pengujian otomatis. Saya bisa berbicara sepanjang hari tentang hal itu.

Latar Belakang

Baru-baru ini, tim kami baru saja mendapatkan proyek besar ini yang dibangun dari awal. Ini adalah aplikasi strategis dengan persyaratan bisnis yang kompleks. Tentu saja, saya ingin itu bagus dan bersih, yang bagi saya berarti: dapat dipelihara dan diuji. Jadi saya ingin menggunakan DI.

Perlawanan

Masalahnya ada di tim kami, DI itu tabu. Sudah dibesarkan beberapa kali, tetapi para dewa tidak menyetujui. Tapi itu tidak membuat saya patah semangat.

Kepindahan saya

Ini mungkin terdengar aneh tetapi perpustakaan pihak ketiga biasanya tidak disetujui oleh tim arsitek kami (pikirkan: "Anda tidak boleh berbicara tentang Persatuan , Ninject , NHibernate , Moq atau NUnit , jangan sampai saya memotong jari Anda"). Jadi, alih-alih menggunakan wadah DI yang sudah mapan, saya menulis wadah yang sangat sederhana. Ini pada dasarnya menghubungkan semua dependensi Anda pada startup, menyuntikkan dependensi (konstruktor / properti) dan membuang objek sekali pakai di akhir permintaan web. Itu sangat ringan dan hanya melakukan apa yang kami butuhkan. Dan kemudian saya meminta mereka untuk memeriksanya.

Responnya

Yah, untuk membuatnya singkat. Saya bertemu dengan perlawanan yang berat. Argumen utama adalah, "Kita tidak perlu menambahkan lapisan kompleksitas ini ke proyek yang sudah rumit". Juga, "Ini tidak seperti kita akan memasukkan implementasi komponen yang berbeda". Dan "Kami ingin membuatnya sederhana, jika mungkin memasukkan semuanya ke dalam satu unit. DI adalah kompleksitas yang tidak dibutuhkan tanpa manfaat".

Akhirnya, Pertanyaan Saya

Bagaimana Anda menangani situasi saya? Saya tidak bagus dalam menyajikan ide-ide saya, dan saya ingin tahu bagaimana orang akan mempresentasikan argumen mereka.

Tentu saja, saya berasumsi bahwa seperti saya, Anda lebih suka menggunakan DI. Jika Anda tidak setuju, tolong katakan mengapa saya bisa melihat sisi lain dari koin. Akan sangat menarik untuk melihat sudut pandang seseorang yang tidak setuju.

Memperbarui

Terima kasih atas jawaban semua orang. Itu benar-benar menempatkan segala sesuatu dalam perspektif. Cukup baik untuk memiliki satu set mata untuk memberi Anda umpan balik, lima belas benar-benar hebat! Ini adalah jawaban yang sangat bagus dan membantu saya melihat masalah dari sisi yang berbeda, tetapi saya hanya dapat memilih satu jawaban, jadi saya hanya akan memilih yang teratas. Terima kasih semuanya telah meluangkan waktu untuk menjawab.

Saya telah memutuskan bahwa ini mungkin bukan waktu terbaik untuk menerapkan DI, dan kami belum siap untuk itu. Sebagai gantinya, saya akan memusatkan upaya saya untuk membuat desain dapat diuji dan berusaha menyajikan pengujian unit otomatis. Saya sadar bahwa tes menulis adalah overhead tambahan dan jika pernah diputuskan bahwa overhead tambahan tidak sepadan, secara pribadi saya masih akan melihatnya sebagai situasi menang karena desain masih dapat diuji. Dan jika pernah menguji atau DI adalah pilihan di masa depan, desain dapat dengan mudah mengatasinya.

Mel
sumber
64
Sepertinya Anda harus pindah ke perusahaan lain ...
Sardathrion
24
Menggunakan DI adalah (setidaknya di Java, C #, ...) hampir merupakan konsekuensi alami dari menggunakan tes unit. Apakah perusahaan Anda menggunakan unit test?
sebastiangeiger
27
Atau tidak fokus pada DI. DI berbeda dari "dipelihara dan diuji". Ketika ada pendapat berbeda tentang suatu proyek, Anda harus menulis dan terkadang menerima bahwa Anda tidak memutuskan. Saya, misalnya, telah melihat bencana yang diperkuat oleh inversi kontrol, DI, dan banyak lapisan kerangka kerja yang membuat hal-hal rumit yang seharusnya sederhana (saya tidak bisa berdebat dalam kasus Anda).
Denys Séguret
34
"... Aku bisa berbicara sepanjang hari tentang hal itu." Sepertinya Anda perlu berhenti terobsesi pada sesuatu yang disalahgunakan lebih sering daripada tidak karena kepatuhan dogmatis terhadap beberapa kertas putih hari itu.
21
Dari suaranya, rekan kerja Anda memiliki argumen obyektif yang menentang penggunaan wadah DI: "kita tidak perlu menambahkan lapisan kompleksitas ini ke proyek yang sudah rumit" - apakah mereka mungkin benar? Apakah Anda sebenarnya mendapat manfaat dari kompleksitas yang ditambahkan? Jika demikian, itu harus dimungkinkan untuk diperdebatkan. Mereka mengklaim bahwa "DI adalah kompleksitas yang tidak perlu tanpa manfaat." Jika Anda dapat menunjukkan manfaat obyektif maka Anda harus memenangkan ini dengan mudah, bukan? Pengujian cukup sering disebutkan dalam komentar lain; tetapi pengujian tidak secara mendasar membutuhkan DI, kecuali jika Anda perlu mengejek (yang tidak diberikan).
Konrad Rudolph

Jawaban:

62

Mengambil beberapa argumen balasan:

"Kami ingin tetap sederhana, jika mungkin hanya memasukkan semuanya ke dalam satu perakitan. DI adalah kompleksitas yang tidak dibutuhkan tanpa manfaat".

"ini tidak seperti kita akan mencolokkan implementasi komponen yang berbeda".

Apa yang Anda inginkan adalah agar sistem dapat diuji. Agar mudah diuji, Anda perlu melihat mengejek berbagai lapisan proyek (database, komunikasi, dll.) Dan dalam hal ini Anda akan mencolokkan berbagai implementasi komponen.

Jual DI pada manfaat pengujian yang diberikannya kepada Anda. Jika proyek ini rumit, maka Anda akan memerlukan pengujian unit yang bagus dan solid.

Manfaat lain adalah bahwa, ketika Anda mengkode ke antarmuka, jika Anda datang dengan implementasi yang lebih baik (lebih cepat, lebih sedikit memori, apa pun) dari salah satu komponen Anda, menggunakan DI membuatnya jauh lebih mudah untuk menukar implementasi lama untuk baru.

Apa yang saya katakan di sini adalah bahwa Anda perlu membahas manfaat yang DI bawa daripada berdebat untuk DI demi DI. Dengan membuat orang menyetujui pernyataan:

"Kita butuh X, Y dan Z"

Anda kemudian mengalihkan masalahnya. Anda perlu memastikan bahwa DI adalah jawaban untuk pernyataan ini. Dengan melakukan itu Anda rekan kerja akan memiliki solusinya daripada merasa bahwa itu telah dibebankan pada mereka.

ChrisF
sumber
+1. Singkat dan to the point. Sayangnya, dari argumen yang dikemukakan oleh rekan kerja Mel, dia akan kesulitan meyakinkan mereka bahwa layak untuk bahkan hanya mencoba - apa yang Spoike katakan dalam jawabannya, lebih merupakan masalah orang daripada masalah teknis.
Patryk Ćwiek
1
@ Trustme-I'maDoctor - Oh saya setuju bahwa ini masalah orang, tetapi dengan pendekatan ini Anda menunjukkan manfaat daripada berdebat untuk DI untuk kepentingannya sendiri.
ChrisF
Benar dan saya berharap dia beruntung, hidupnya sebagai pengembang akan lebih mudah dengan testability yang tepat, dll :)
Patryk Ćwiek
4
+1 Saya pikir paragraf terakhir Anda harus menjadi yang pertama. Itu adalah pusat masalah. Jika kemampuan untuk Tes Unit didorong dan mengubah seluruh sistem menjadi model DI disarankan, saya akan mengatakan tidak kepadanya juga.
Andrew T Finnell
+1 memang sangat membantu. Saya tidak akan mengatakan DI adalah suatu keharusan mutlak untuk pengujian unit tetapi hal itu membuat segalanya menjadi jauh lebih mudah.
Mel
56

Dari apa yang Anda tulis, bukan DI itu sendiri adalah tabu, tetapi penggunaan wadah DI, yang merupakan hal yang berbeda. Saya kira Anda tidak akan mendapatkan masalah dengan tim Anda ketika Anda hanya menulis komponen independen yang mendapatkan komponen lain yang mereka perlukan, misalnya, oleh konstruktor. Hanya saja, jangan menyebutnya "DI".

Anda mungkin berpikir untuk komponen seperti itu untuk tidak menggunakan wadah DI itu membosankan, dan Anda benar, tetapi berikan waktu pada tim Anda untuk mencari tahu sendiri.

Doc Brown
sumber
10
+1 solusi pragmatis ke jalan buntu politik / dogmatis
k3b
32
Sebaiknya pertimbangkan memasang semua objek Anda secara manual, dan memperkenalkan wadah DI hanya ketika itu mulai menjadi berbulu. Jika Anda melakukan ini, mereka tidak akan melihat wadah DI sebagai kompleksitas tambahan - mereka akan melihatnya sebagai menambahkan kesederhanaan.
Phil
2
Satu-satunya masalah adalah bahwa pola meneruskan dependensi yang ditambah secara longgar ke dependen adalah DI. IoC, atau penggunaan "wadah" untuk menyelesaikan dependensi yang longgar, adalah DI otomatis .
KeithS
51

Karena Anda bertanya, saya akan memihak tim Anda melawan DI.

Kasus terhadap Injeksi Ketergantungan

Ada aturan yang saya sebut "Konservasi Kompleksitas" yang analog dengan aturan dalam fisika yang disebut "Konservasi Energi." Ini menyatakan bahwa tidak ada jumlah rekayasa yang dapat mengurangi kompleksitas total dari solusi optimal untuk suatu masalah, yang dapat dilakukan hanyalah menggeser kompleksitas tersebut. Produk Apple tidak kalah kompleksnya dengan produk Microsoft, mereka hanya memindahkan kompleksitas dari ruang pengguna ke ruang teknik. (Ini adalah analogi yang cacat, meskipun. Meskipun Anda tidak dapat membuat energi, insinyur memiliki kebiasaan buruk dalam menciptakan kompleksitas di setiap kesempatan. Bahkan, banyak programmer tampaknya menikmati penambahan kompleksitas dan menggunakan sihir, yang menurut kompleksitasnya tidak sepenuhnya dipahami oleh programmer. Kerumitan berlebih ini dapat dikurangi.) Biasanya yang tampak seperti mengurangi kompleksitas hanyalah memindahkan kompleksitas ke tempat lain, biasanya ke perpustakaan.

Demikian pula, DI tidak mengurangi kompleksitas menghubungkan objek klien dengan objek server. Apa yang dilakukannya adalah mengeluarkannya dari Jawa dan memindahkannya ke XML. Itu bagus karena memusatkan segala sesuatu menjadi satu (atau beberapa) file XML di mana mudah untuk melihat semua yang sedang terjadi dan di mana dimungkinkan untuk mengubah hal-hal tanpa mengkompilasi ulang kode. Di sisi lain, itu buruk karena file XML bukan Java dan karenanya tidak tersedia untuk tooling Java. Anda tidak dapat men-debug mereka di debugger, Anda tidak dapat menggunakan analisis statis untuk melacak hierarki panggilan mereka, dan seterusnya. Secara khusus, bug dalam kerangka DI menjadi sangat sulit untuk dideteksi, diidentifikasi, dan diperbaiki.

Oleh karena itu jauh lebih sulit untuk membuktikan suatu program menjadi benar ketika menggunakan DI. Banyak orang berpendapat bahwa program yang menggunakan DI lebih mudah untuk diuji , tetapi pengujian program tidak pernah dapat membuktikan tidak adanya bug . (Perhatikan bahwa makalah yang ditautkan berusia sekitar 40 tahun dan karenanya memiliki beberapa referensi misterius dan mengutip beberapa praktik kedaluwarsa, tetapi banyak pernyataan dasar masih berlaku. Terutama, bahwa P <= p ^ n, di mana P adalah probabilitas bahwa sistem bebas dari bug, p adalah probabilitas bahwa komponen sistem bebas dari bug, dan n adalah jumlah komponen. Tentu saja, persamaan ini terlalu disederhanakan, tetapi menunjuk pada kebenaran penting.) NASDAQ mogok saat IPO Facebook adalah contoh terbaru, di manamereka mengklaim telah menghabiskan 1.000 jam menguji kode dan masih belum menemukan bug yang menyebabkan crash. 1.000 jam adalah setengah tahun orang, jadi itu tidak seperti mereka berhemat pada pengujian.

Benar, hampir tidak ada yang pernah melakukan (apalagi menyelesaikan) tugas membuktikan kode secara formal adalah benar, tetapi bahkan upaya yang lemah pada bukti mengalahkan sebagian besar rezim pengujian untuk menemukan bug. Upaya keras untuk pembuktian, misalnya L4.verified , selalu menemukan sejumlah besar bug yang tidak diuji dan mungkin tidak akan pernah terungkap kecuali penguji sudah mengetahui sifat pasti dari bug tersebut. Apa pun yang membuat kode lebih sulit untuk diverifikasi dengan inspeksi dapat dilihat sebagai mengurangi kemungkinan bug akan terdeteksi , bahkan jika itu meningkatkan kemampuan untuk menguji.

Selanjutnya DI tidak diperlukan untuk pengujian . Saya jarang menggunakannya untuk tujuan itu, karena saya lebih suka menguji sistem terhadap perangkat lunak nyata dalam sistem daripada beberapa versi pengujian alternatif. Segala sesuatu yang saya ubah dalam pengujian (atau mungkin juga) disimpan dalam file properti yang mengarahkan program ke sumber daya di lingkungan pengujian daripada produksi. Saya lebih suka menghabiskan waktu menyiapkan server database pengujian dengan salinan basis data produksi daripada menghabiskan waktu menyusun database tiruan, karena dengan cara ini saya akan dapat melacak masalah dengan data produksi (masalah pengkodean karakter hanyalah salah satu contoh ) dan bug integrasi sistem serta bug dalam sisa kode.

Ketergantungan Injeksi juga tidak diperlukan untuk Ketergantungan Inversi . Anda dapat dengan mudah menggunakan metode pabrik statis untuk mengimplementasikan Pembalikan Ketergantungan. Sebenarnya, itulah yang dilakukan pada 1990-an.

Sebenarnya, meskipun saya telah menggunakan DI selama satu dekade, satu-satunya keuntungan yang saya temukan persuasif adalah kemampuan untuk mengkonfigurasi perpustakaan pihak ketiga untuk menggunakan perpustakaan pihak ketiga lainnya (misalnya mengatur Spring untuk menggunakan Hibernate dan keduanya untuk menggunakan Log4J ) dan mengaktifkan IoC melalui proksi. Jika Anda tidak menggunakan perpustakaan pihak ketiga dan tidak menggunakan IoC, maka tidak ada banyak gunanya dan itu memang menambah kompleksitas yang tidak beralasan.

Old Pro
sumber
1
Saya tidak setuju, itu mungkin untuk mengurangi kompleksitas. Saya tahu karena saya sudah melakukannya. Tentu saja, beberapa masalah / persyaratan memaksa kompleksitas, tetapi di atas itu sebagian besar dapat dihilangkan dengan usaha.
Ricky Clarkson
10
@ Ricky, ini perbedaan yang halus. Seperti yang saya katakan, para insinyur dapat menambahkan kompleksitas, dan kompleksitas itu dapat dihilangkan, sehingga Anda mungkin telah mengurangi kompleksitas implementasi, tetapi menurut definisi Anda tidak dapat mengurangi kompleksitas solusi optimal untuk suatu masalah. Paling sering apa yang tampak seperti mengurangi kompleksitas hanya menggesernya ke tempat lain (biasanya ke perpustakaan). Dalam hal apa pun itu adalah titik kedua dari poin utama saya yaitu DI yang tidak mengurangi kompleksitas.
Old Pro
2
@ Lee, mengkonfigurasi DI dalam kode bahkan kurang berguna. Salah satu manfaat DI yang paling banyak diterima adalah kemampuan untuk mengubah implementasi layanan tanpa mengkompilasi ulang kode, dan jika Anda mengkonfigurasi DI dalam kode, maka Anda kehilangan itu.
Old Pro
7
@OldPro - Mengkonfigurasi dalam kode memiliki manfaat keamanan tipe, dan sebagian besar dependensi bersifat statis dan tidak memiliki manfaat jika didefinisikan secara eksternal.
Lee
3
@ Lee Jika dependensinya statis, mengapa mereka tidak dikodekan sejak awal, tanpa jalan memutar melalui DI?
Konrad Rudolph
25

Saya minta maaf untuk mengatakan bahwa masalah yang Anda miliki, mengingat apa yang dikatakan rekan kerja Anda dalam pertanyaan Anda, lebih bersifat politis daripada teknis. Ada dua mantra yang harus Anda ingat:

  • "Itu selalu masalah orang"
  • " Perubahan itu menakutkan"

Tentu, Anda dapat memunculkan banyak argumen balasan dengan alasan dan manfaat teknis yang solid, tetapi itu akan menempatkan Anda dalam situasi yang buruk dengan anggota perusahaan lainnya. Mereka sudah memiliki sikap yang tidak mereka inginkan (karena mereka merasa nyaman dengan cara kerja sekarang). Jadi, bahkan mungkin akan merusak hubungan Anda dengan rekan-rekan sejawat Anda jika Anda tetap gigih tentang hal itu. Percayalah pada saya karena ini telah terjadi pada saya dan pada akhirnya membuat saya dipecat beberapa tahun yang lalu (muda dan naif seperti saya); ini adalah situasi yang tidak Anda inginkan.

Masalahnya adalah, Anda perlu mencapai tingkat kepercayaan sebelum orang pergi sejauh mengubah cara kerja mereka saat ini. Kecuali Anda berada dalam posisi di mana Anda memiliki banyak kepercayaan atau Anda dapat memutuskan hal-hal seperti ini, seperti memiliki peran sebagai arsitek atau pemimpin teknologi, ada sangat sedikit yang dapat Anda lakukan untuk mengubah rekan kerja Anda. Dibutuhkan banyak waktu dengan bujukan dan upaya (seperti dalam mengambil langkah-langkah perbaikan kecil) untuk mendapatkan kepercayaan agar budaya perusahaan Anda berubah. Kita berbicara tentang rentang waktu berbulan-bulan atau bertahun-tahun.

Jika Anda menemukan bahwa budaya perusahaan saat ini tidak bekerja dengan Anda maka setidaknya Anda tahu satu hal lagi untuk ditanyakan pada wawancara kerja Anda berikutnya. ;-)

Spoike
sumber
23

Jangan gunakan DI. Lupakan.

Buat implementasi dari pola pabrik GoF yang "menciptakan" atau "menemukan" dependensi khusus Anda dan meneruskannya ke objek Anda dan biarkan saja, tetapi jangan menyebutnya DI dan jangan buat kerangka kerja umum yang rumit. Tetap sederhana dan relevan. Pastikan dependensi dan kelas Anda sedemikian rupa sehingga peralihan ke DI dimungkinkan; tetapi jaga agar pabrik tetap menjadi master dan jaga agar lingkupnya sangat terbatas.

Pada waktunya, Anda dapat berharap bahwa itu akan tumbuh dan bahkan satu hari transisi ke DI. Biarkan lead sampai pada kesimpulan pada waktunya sendiri dan jangan mendorong. Sekalipun Anda tidak pernah mencapai hal itu, setidaknya kode Anda memiliki beberapa kelebihan DI, misalnya, kode unit yang dapat diuji.

jasonk
sumber
3
+1 untuk tumbuh bersama dengan proyek dan "jangan menyebutnya DI"
Kevin McCormick
5
Saya setuju, tetapi pada akhirnya adalah DI. Hanya saja tidak menggunakan wadah DI; itu menyerahkan beban kepada penelepon daripada memusatkannya di satu tempat. Namun, akan lebih pintar untuk menyebutnya "Ketergantungan Eksternalisasi" daripada DI.
Juan Mendes
5
Sering terpikir oleh saya bahwa untuk benar-benar memahami konsep menara gading seperti DI, Anda harus melalui proses yang sama seperti yang dilakukan oleh para penginjil untuk menyadari bahwa ada masalah yang harus dipecahkan sejak awal. Penulis sering melupakan ini. Tetap menggunakan bahasa pola level rendah dan kebutuhan akan wadah mungkin (atau mungkin tidak) muncul sebagai akibatnya.
Tom W
@JuanMendes dari tanggapan mereka, saya berpikir bahwa dependensi eksternalisasi adalah apa yang mereka lawan karena mereka juga tidak suka perpustakaan pihak ketiga dan menginginkan semuanya dalam satu perakitan (monolit?). Jika itu benar maka menyebutnya "Ketergantungan Eksternalisasi" tidak lebih baik daripada memanggil DI dari sudut pandang mereka.
Jonathan Neufeld
22

Saya telah melihat proyek yang membawa DI ke ekstrem untuk menguji unit dan mengejek objek. Sedemikian rupa sehingga konfigurasi DI menjadi bahasa pemrograman itu sendiri dengan konfigurasi sebanyak yang diperlukan untuk membuat sistem berjalan sebagai kode aktual.

Apakah sistem menderita saat ini karena kurangnya API internal yang sesuai yang tidak dapat diuji? Apakah Anda berharap bahwa beralih sistem ke model DI akan memungkinkan Anda untuk menguji unit lebih baik? Anda tidak perlu wadah untuk menguji unit kode Anda. Menggunakan model DI akan memungkinkan Anda untuk mengujinya dengan lebih mudah dengan benda-benda Mock, tetapi tidak diperlukan.

Anda tidak perlu mengganti seluruh sistem agar menjadi kompatibel DI sekaligus. Anda tidak boleh secara sewenang-wenang menulis tes Unit juga. Kode refactor saat Anda menemukannya di fitur Anda dan bug tiket yang berfungsi. Kemudian pastikan kode yang Anda sentuh mudah diuji.

Pikirkan CodeRot sebagai penyakit. Anda tidak ingin memulai dengan sewenang-wenang meretas sesuatu. Anda memiliki seorang pasien, Anda melihat tempat yang sakit, sehingga Anda mulai memperbaiki tempat itu dan hal-hal di sekitarnya. Setelah area itu bersih, Anda beralih ke yang berikutnya. Cepat atau lambat Anda akan menyentuh sebagian besar kode dan tidak memerlukan perubahan arsitektur "besar" ini.

Saya tidak suka pengujian DI dan Mock saling eksklusif. Dan setelah melihat proyek yang berjalan, karena tidak ada kata yang lebih baik, gila menggunakan DI, saya akan lelah juga tanpa melihat manfaatnya.

Ada beberapa tempat yang masuk akal untuk menggunakan DI:

  • Layer Akses Data untuk menukar strategi untuk data storying
  • Lapisan Otentikasi dan Otorisasi.
  • Tema untuk Antarmuka Pengguna
  • Jasa
  • Poin ekstensi plugin yang dapat digunakan sistem Anda atau pihak ketiga.

Memerlukan setiap pengembang untuk mengetahui di mana file konfigurasi DI (Saya menyadari kontainer dapat dibuatkan contoh melalui kode, tetapi mengapa Anda melakukan itu.) Ketika mereka ingin melakukan RegEx frustasi. Oh saya melihat ada IRegExCompiler, DefaultRegExCompiler dan SuperAwesomeRegExCompiler. Namun tidak ada di mana dalam kode saya bisa melakukan analisis untuk melihat di mana Default digunakan dan SuperAwesome digunakan.

Kepribadian saya sendiri akan bereaksi lebih baik jika seseorang menunjukkan kepada saya sesuatu yang lebih baik, kemudian mencoba meyakinkan saya dengan kata-kata mereka. Ada sesuatu yang bisa dikatakan tentang seseorang yang akan meluangkan waktu dan upaya untuk membuat sistem lebih baik. Saya tidak menemukan banyak pengembang yang cukup peduli untuk membuat produk ini benar-benar lebih baik. Jika Anda bisa mendatanginya dengan perubahan nyata dalam sistem dan menunjukkan kepada mereka bagaimana hal itu membuatnya lebih baik dan lebih mudah bagi Anda, itu lebih berharga daripada riset online mana pun.

Singkatnya, cara terbaik untuk melakukan perubahan menjadi suatu sistem adalah dengan perlahan membuat kode yang saat ini Anda sentuh lebih baik setiap kali lewat. Cepat atau lambat Anda akan dapat mengubah sistem menjadi sesuatu yang lebih baik.

Andrew Finnell
sumber
"Pengujian DI dan Mock saling eksklusif" Itu salah, mereka juga tidak saling inklusif. Mereka hanya bekerja bersama dengan baik. Anda juga daftar tempat-tempat DI baik, lapisan layanan, dao dan antarmuka pengguna - itu hampir di mana-mana bukan?
NimChimpsky
@Andrew poin yang valid. Tentu saja, saya tidak ingin terlalu jauh. Saya paling menginginkan pengujian otomatis untuk kelas bisnis, karena kami harus menerapkan aturan bisnis yang sangat kompleks. Dan saya sadar saya masih bisa mengujinya tanpa wadah, tetapi secara pribadi, masuk akal untuk menggunakan wadah. Saya sebenarnya melakukan sedikit sampel yang menunjukkan konsep. Tapi itu bahkan tidak dilihat. Saya kira kesalahan saya adalah saya tidak membuat tes yang menunjukkan betapa mudahnya pengujian / mengejek.
Mel
Begitu banyak kesepakatan! Saya benar-benar sangat membenci file konfigurasi DI dan efeknya pada pelacakan aliran program. Semuanya berubah menjadi "aksi seram di kejauhan" tanpa koneksi yang jelas antara potongan-potongan. Ketika menjadi lebih mudah untuk membaca kode di debugger daripada di file sumber, ada sesuatu yang salah.
Zan Lynx
19

DI tidak memerlukan inversi wadah Kontrol invasif atau kerangka kerja mengejek. Anda dapat memisahkan kode dan mengizinkan DI melalui desain sederhana. Anda dapat melakukan pengujian unit melalui kemampuan Visual Studio bawaan.

Agar adil, rekan kerja Anda ada benarnya. Menggunakan perpustakaan-perpustakaan itu dengan buruk (dan karena mereka tidak terbiasa dengan itu, akan ada rasa sakit belajar) akan menimbulkan masalah. Pada akhirnya, masalah kode. Jangan mengacaukan produk Anda untuk pengujian Anda.

Ingatlah bahwa kompromi diperlukan dalam skenario ini.

Telastyn
sumber
2
Saya setuju DI tidak memerlukan wadah IOC. walaupun saya tidak akan menyebutnya invasif (implementasi ini setidaknya) karena kode ini dirancang untuk menjadi wadah agnostik (kebanyakan injeksi konstruktor) dan semua hal DI terjadi di satu tempat. Jadi semuanya masih berfungsi tanpa wadah DI - saya memasukkan konstruktor tanpa parameter yang "menyuntikkan" implementasi konkret ke konstruktor lain dengan dependensi. Dengan begitu saya masih bisa dengan mudah mengejeknya. Jadi ya saya setuju, DI sebenarnya dicapai oleh desain.
Mel
+1 Untuk kompromi. Jika tidak ada yang mau kompromi, semua orang akhirnya menderita.
Tjaart
14

Saya tidak berpikir bahwa Anda dapat menjual DI lagi, karena ini adalah keputusan dogmatis (atau, seperti @Spoike menyebutnya lebih sopan, politis ).

Dalam Situasi ini berdebat dengan praktik terbaik yang diterima secara luas seperti prinsip desain SOLID tidak mungkin lagi.

Seseorang yang memiliki kekuatan politik lebih dari Anda telah membuat (mungkin salah) keputusan untuk tidak menggunakan DI.

Anda di pihak lain telah menentang keputusan ini dengan menerapkan wadah Anda sendiri karena dilarang menggunakan wadah yang sudah ada. Ini kebijakan faits accompli yang Anda mencoba mungkin telah membuat situasi lebih buruk.

Analisis

Menurut pendapat saya, DI tanpa pengembangan testdriven (TDD) dan pengujian unit tidak memiliki manfaat signifikan yang melebihi biaya tambahan awal.

Apakah masalah ini benar-benar tentang

  • kita tidak mau DI ?

atau ini tentang

  • tdd / unittesting adalah pemborosan sumber daya ?

[Memperbarui]

Jika Anda melihat proyek Anda dari kesalahan klasik dalam tampilan manajemen proyek , Anda tahu

#12: Politics placed over substance.
#21: Inadequate design. 
#22: Shortchanged quality assurance.
#27: Code-like-hell programming.

sementara yang lain melihat

#3: Uncontrolled problem employees. 
#30: Developer gold-plating. 
#32: Research-oriented development. 
#34: Overestimated savings from new tools or methods. 
k3b
sumber
saat ini kami tidak melakukan pengujian unit apa pun di tim kami. Saya menduga bahwa pernyataan terakhir Anda tepat. Saya telah mengemukakan unit testing beberapa kali tetapi tidak ada yang menunjukkan minat nyata di dalamnya dan selalu ada alasan mengapa kami tidak bisa mengadopsinya.
Mel
10

Jika Anda harus "menjual" prinsip ke tim Anda, maka Anda mungkin sudah beberapa mil di jalan yang salah.

Tidak ada yang ingin melakukan pekerjaan ekstra, jadi jika apa yang Anda coba jual terlihat seperti kerja ekstra, maka Anda tidak akan meyakinkan mereka dengan Invocation of Superior Argument. Mereka perlu tahu bahwa Anda menunjukkan kepada mereka cara untuk mengurangi beban kerja mereka, bukan menambahnya.

DI sering dipandang sebagai kompleksitas ekstra sekarang dengan janji potensi kompleksitas yang berkurang di kemudian hari , yang memiliki nilai, tetapi tidak begitu bagi seseorang yang berusaha mengurangi beban kerja dimuka mereka. Dan dalam banyak kasus, DI hanyalah lapisan YAGNI . Dan biaya kerumitan ini bukan nol, sebenarnya cukup tinggi untuk tim yang tidak terbiasa dengan pola jenis ini. Dan itu adalah uang nyata yang disekop ke dalam ember yang mungkin tidak pernah menghasilkan manfaat apa pun.

Taruh di tempatnya
Taruhan terbaik Anda adalah menggunakan DI di mana itu sangat berguna, bukan hanya di tempat yang biasa. Misalnya, banyak aplikasi menggunakan DI untuk memilih dan mengkonfigurasi basis data. Dan jika aplikasi Anda dikirimkan dengan lapisan basis data maka itu adalah tempat yang menggoda untuk meletakkannya. Tetapi jika aplikasi Anda dikirimkan dengan database yang tidak terlihat oleh pengguna yang terintegrasi dengan kode, maka kemungkinan perlu mengganti DB saat mendekati nol. Dan menjual DI dengan mengatakan, "lihat, kita dapat dengan mudah melakukan hal ini yang tidak akan pernah, ingin kita lakukan," kemungkinan membuat Anda masuk dalam daftar "orang ini punya ide buruk" dengan bos Anda.

Tetapi katakan sebaliknya Anda memiliki hasil debug yang biasanya dikeluarkan IFDEF dalam rilis. Dan setiap kali pengguna memiliki masalah, tim dukungan Anda harus mengirim mereka debug build agar mereka bisa mendapatkan output log. Anda dapat menggunakan DI di sini untuk memungkinkan pelanggan untuk beralih di antara driver log - LogConsoleuntuk pengembang, LogNulluntuk pelanggan, dan LogNetworkuntuk pelanggan dengan masalah. Satu bangunan terpadu, runtime dapat dikonfigurasi.

Maka Anda bahkan tidak harus menyebutnya DI, sebaliknya itu hanya disebut "ide bagus Mel" dan Anda sekarang berada di daftar ide bagus bukan yang buruk. Orang-orang akan melihat seberapa baik polanya bekerja, dan mulai menggunakannya di tempat yang masuk akal dalam kode mereka.

Ketika Anda menjual ide dengan benar, orang tidak akan tahu bahwa Anda meyakinkan mereka tentang apa pun.

tylerl
sumber
8

Tentu saja, Inversion of control (IoC) memiliki sejumlah besar manfaat: ia menyederhanakan kode, menambahkan beberapa keajaiban yang melakukan tugas-tugas khas, dll.

Namun:

  1. Ini menambah banyak dependensi. Aplikasi hello world sederhana yang ditulis dengan Spring dapat memberi bobot selusin MB, dan saya telah melihat Spring ditambahkan hanya untuk menghindari beberapa baris konstruktor dan setter.

  2. Ia menambahkan keajaiban yang disebutkan di atas , yang sulit dipahami oleh orang luar (misalnya, pengembang GUI yang perlu membuat beberapa perubahan di lapisan bisnis). Lihat artikel hebat Pikiran Inovatif Jangan Berpikir Sama - New York Times , yang menggambarkan bagaimana efek ini diremehkan oleh para ahli .

  3. Itu mengeras untuk melacak penggunaan kelas. IDE seperti Eclipse memiliki kemampuan hebat untuk melacak penggunaan kelas atau pemanggilan metode tertentu. Tapi jejak ini hilang ketika ada injeksi ketergantungan dan refleksi dipanggil.

  4. Penggunaan IoC biasanya tidak berakhir dengan ketergantungan injeksi, diakhiri dengan proxy yang tak terhitung jumlahnya, dan Anda mendapatkan tumpukan jejak menghitung ratusan baris, 90% di antaranya adalah proxy dan dipanggil melalui refleksi. Ini sangat menyulitkan menganalisis tumpukan jejak.

Jadi, saya sendiri penggemar berat Spring dan IoC, saya baru-baru ini harus memikirkan kembali pertanyaan di atas. Beberapa kolega saya adalah pengembang web yang diambil di dalam dunia Java dari dunia Web yang dikuasai oleh Python dan PHP dan yang jelas untuk hal-hal java adalah sesuatu yang jelas bagi mereka. Beberapa kolega saya yang lain melakukan trik (tentu saja tidak berdokumen) yang membuat kesalahan sangat sulit ditemukan. Tentu saja penyalahgunaan IoC membuat segalanya lebih ringan untuk mereka;)

Saran saya, jika Anda akan memaksakan penggunaan IoC dalam pekerjaan Anda, Anda akan bertanggung jawab atas penyalahgunaan yang dilakukan orang lain;)

Łukasz Lech
sumber
Memberi +1 sama seperti setiap alat canggih lainnya, mudah disalahgunakan dan Anda HARUS mengerti kapan TIDAK menggunakannya.
Phil
4

Saya pikir ChrisF adalah sesuatu yang benar. Jangan menjual DI sendiri. Tetapi jual ide tentang unit yang menguji kode.

Salah satu pendekatan untuk memasukkan wadah DI ke dalam arsitektur bisa dengan perlahan membiarkan tes mendorong implementasi menjadi sesuatu yang cocok dengan arsitektur itu. Misalnya katakanlah Anda sedang mengerjakan pengontrol di aplikasi ASP.NET MVC. Katakanlah Anda menulis kelas seperti ini:

public class UserController {
    public UserController() : this (new UserRepository()) {}

    public UserController(IUserRepository userRepository) {
        ...
    }

    ...
}

Itu memungkinkan Anda untuk menulis unit test yang dipisahkan dari implementasi sebenarnya dari repositori pengguna. Tetapi kelas masih bekerja tanpa wadah DI untuk membuatnya untuk Anda. Konstruktor tanpa parameter akan membuatnya dengan repositori default.

Jika Anda rekan kerja dapat melihat bahwa ini mengarah pada tes yang lebih bersih, mungkin mereka dapat menyadari bahwa itu adalah cara yang lebih baik. Mungkin Anda bisa membuat mereka mulai mengkode seperti itu.

Setelah mereka menyadari bahwa ini adalah desain yang lebih baik daripada UserController mengetahui tentang implementasi UserRepository tertentu, Anda dapat mengambil langkah selanjutnya, dan menunjukkan kepada mereka bahwa Anda dapat memiliki komponen, wadah DI, yang secara otomatis dapat menyediakan contoh yang Anda butuhkan.

Pete
sumber
Bagus! Saya saat ini melakukan ini karena saya benar-benar ingin pengujian unit otomatis, bahkan jika saya tidak bisa mendapatkan DI. Saya lupa menyebutkan bahwa tes unit juga tidak dilakukan di tim kami :( jadi jika saya akan menjadi yang pertama.
Mel
2
Kalau begitu, saya akan mengatakan itu masalah sebenarnya di sini. Temukan akar resistensi terhadap pengujian unit, dan serang itu. Biarkan DI berbohong untuk saat ini. Pengujian IMHO lebih penting.
Christian Horsdal
@ChristianHorsdal Saya setuju, saya ingin itu digabungkan secara longgar untuk memudahkan mengejek / pengujian.
Mel
Gagasan itu sangat keren ... Jual hebat untuk pengujian
bunglestink
2

Mungkin hal terbaik untuk dilakukan adalah mundur dan bertanya pada diri sendiri mengapa Anda ingin memperkenalkan wadah DI? Jika itu untuk meningkatkan testabilitas maka Anda tugas pertama Anda adalah membuat tim untuk membeli ke unit testing. Secara pribadi saya akan jauh lebih khawatir tentang kurangnya unit test daripada kurangnya wadah DI.

Dipersenjatai dengan suite atau suite unit test yang komprehensif, Anda dapat dengan percaya diri mulai mengembangkan desain Anda dari waktu ke waktu. Tanpa mereka, Anda menghadapi perjuangan yang semakin penuh untuk mempertahankan desain Anda selangkah demi selangkah dengan persyaratan yang berkembang, perjuangan yang akhirnya banyak tim kalah.

Jadi saran saya akan menjadi juara pertama pengujian dan refactoring unit kemudian, pada gilirannya memperkenalkan wadah DI dan akhirnya.

kimj100
sumber
2

Saya mendengar beberapa no-no besar dari tim Anda di sini:

  • "Tidak ada perpustakaan pihak ketiga" - AKA "Tidak Diciptakan Di Sini" atau "NIH". Ketakutan adalah bahwa, dengan mengimplementasikan perpustakaan pihak ketiga dan dengan demikian membuat basis kode bergantung padanya, jika perpustakaan memiliki bug, atau lubang keamanan, atau bahkan hanya batasan yang perlu Anda atasi, Anda menjadi tergantung pada ketiga ini pihak untuk memperbaiki perpustakaan mereka agar kode Anda berfungsi. Sementara itu, karena program "Anda" yang gagal spektakuler, atau diretas, atau tidak melakukan apa yang mereka minta, Anda masih memikul tanggung jawab (dan para pengembang pihak ketiga akan mengatakan bahwa alat mereka "apa adanya" ", gunakan dengan resiko Anda sendiri).

    Argumen kontra adalah bahwa kode yang memecahkan masalah sudah ada di perpustakaan pihak ketiga. Apakah Anda membangun komputer dari awal? Apakah Anda menulis Visual Studio? Apakah Anda menghindari pustaka bawaan di .NET? Tidak. Anda memiliki tingkat kepercayaan pada Intel / AMD dan Microsoft, dan mereka menemukan bug setiap saat (dan tidak selalu memperbaikinya dengan cepat). Menambahkan perpustakaan pihak ketiga memungkinkan Anda untuk dengan cepat membuat basis kode yang dapat dipertahankan berfungsi, tanpa harus menemukan kembali kemudi. Dan sepasukan pengacara Microsoft akan menertawakan Anda ketika Anda memberi tahu mereka bahwa bug di perpustakaan .NET cryptography membuat mereka bertanggung jawab atas insiden peretasan yang diderita klien Anda saat menggunakan program .NET Anda. Sementara Microsoft pasti akan melompat untuk memperbaiki lubang keamanan "nol-jam" di salah satu produknya,

  • "Kami ingin memasukkan semuanya menjadi satu perakitan" - sebenarnya, Anda tidak. Di .NET setidaknya, jika Anda membuat perubahan ke satu baris kode seluruh perakitan yang mengandung baris kode itu harus dibangun kembali. Desain kode yang baik didasarkan pada beberapa majelis yang dapat Anda bangun kembali secara mandiri (atau setidaknya hanya harus membangun kembali dependensi, bukan tanggungan). Jika mereka BENAR-BENAR ingin merilis EXE yang hanya EXE (yang memang memiliki nilai dalam keadaan tertentu), ada aplikasi untuk itu; ILMerge.

  • "DI itu tabu" - WTF? DI adalah praktik terbaik yang diterima dalam bahasa O / O dengan konstruksi kode "antarmuka". Bagaimana tim Anda mematuhi metodologi desain GRASP atau SOLID jika mereka tidak secara longgar menggabungkan ketergantungan antara objek? Jika mereka tidak repot-repot, maka mereka mengabadikan pabrik spageti yang membuat produk itu semakin rumit. Sekarang, DI memang meningkatkan kompleksitas dengan meningkatkan jumlah objek, dan sementara itu membuat penggantian implementasi yang berbeda lebih mudah, itu membuat mengubah antarmuka itu sendiri lebih sulit (dengan menambahkan lapisan tambahan objek kode yang harus diubah).

  • "Kami tidak perlu menambahkan lapisan kompleksitas ini ke proyek yang sudah rumit" - Mereka mungkin ada benarnya. Suatu hal penting untuk dipertimbangkan dalam pengembangan kode adalah YAGNI; "Kamu Tidak Akan Membutuhkannya". Desain yang direkayasa secara SOLID dari awal adalah desain yang dibuat SOLID "berdasarkan iman"; Anda tidak tahu apakah Anda akan membutuhkan kemudahan perubahan yang disediakan desain SOLID, tetapi Anda punya firasat. Meskipun Anda mungkin benar, Anda juga mungkin sangat salah; desain yang sangat SOLID dapat akhirnya dilihat sebagai "kode lasagna" atau "kode ravioli", memiliki begitu banyak lapisan atau potongan ukuran gigitan yang membuat perubahan yang tampaknya sepele menjadi sulit karena Anda harus menggali melalui begitu banyak lapisan dan / atau melacak melalui tumpukan panggilan yang berbelit-belit.

    Saya mendukung aturan tiga pukulan: Buat itu berfungsi, bersihkan, buat SOLID. Saat Anda pertama kali menulis sebaris kode, kode itu harus bekerja, dan Anda tidak mendapatkan poin untuk desain menara gading. Anggap itu hanya satu kali dan lakukan apa yang harus Anda lakukan. Kali kedua Anda melihat kode itu, Anda mungkin ingin memperluas atau menggunakannya kembali, dan bukan itu yang Anda pikir akan terjadi. Pada titik ini, buat lebih elegan dan mudah dipahami dengan refactoring; sederhanakan logika berbelit-belit, ekstrak kode berulang menjadi loop dan / atau panggilan metode, tambahkan beberapa komentar di sana-sini untuk setiap kludge Anda harus meninggalkan di tempat, dll. Ketiga kalinya Anda melihat kode itu mungkin semacam masalah besar. Sekarang Anda harus mematuhi aturan SOLID; menyuntikkan dependensi alih-alih membangunnya, mengekstrak kelas untuk menyimpan metode yang kurang kohesif dengan "daging" kode,

  • "Ini tidak seperti kita akan melakukan implementasi yang berbeda" - Anda, Pak, memiliki tim yang tidak percaya pada tes unit di tangan Anda. Saya berpendapat bahwa tidak mungkin untuk menulis unit test, yang berjalan dalam isolasi dan tidak memiliki efek samping, tanpa dapat "mengejek" objek yang memiliki efek samping tersebut. Setiap program non-sepele memiliki efek samping; jika program Anda membaca atau menulis ke DB, membuka atau menyimpan file, berkomunikasi melalui jaringan atau soket periferal, meluncurkan program lain, menggambar windows, output ke konsol, atau menggunakan memori atau sumber daya di luar "kotak pasir" prosesnya, ia memiliki efek samping. Jika tidak melakukan hal-hal ini, apa yang DILAKUKAN, dan mengapa saya harus membelinya?

    Agar adil, pengujian unit bukan satu-satunya cara untuk membuktikan program bekerja; Anda dapat menulis tes integrasi, kode ke algoritme yang terbukti secara matematis, dll. Namun, pengujian unit menunjukkan, dengan sangat cepat, yang memberikan input A, B dan C, kode ini menghasilkan output X yang diharapkan (atau tidak), dan dengan demikian kode berfungsi dengan baik (atau tidak) dalam kasus yang diberikan. Rangkaian pengujian unit dapat menunjukkan dengan tingkat keyakinan yang tinggi bahwa kode berfungsi seperti yang diharapkan dalam semua kasus, dan mereka juga memberikan sesuatu yang tidak bisa dibuktikan oleh bukti matematis; sebuah demonstrasi bahwa program MASIH bekerja sebagaimana mestinya. Bukti matematis dari algoritma tidak membuktikan itu diterapkan dengan benar, juga tidak membuktikan perubahan yang dibuat diimplementasikan dengan benar dan tidak merusaknya.

Singkatnya adalah bahwa, jika tim ini tidak melihat nilai apa pun yang akan dilakukan DI, maka mereka tidak akan mendukungnya, dan semua orang (setidaknya semua orang senior) harus membeli sesuatu untuk perubahan nyata terjadi. Mereka banyak menekankan pada YAGNI. Anda memberi banyak penekanan pada pengujian SOLID dan otomatis. Di suatu tempat di tengah terletak kebenaran.

KeithS
sumber
1

Hati-hati menambahkan fitur tambahan (seperti DI) ke proyek ketika tidak disetujui. Jika Anda memiliki rencana proyek dengan batas waktu, Anda dapat terjebak dalam perangkap karena tidak memiliki cukup waktu untuk menyelesaikan fitur yang disetujui.

Bahkan jika Anda tidak menggunakan DI sekarang, ikut serta dalam pengujian sehingga Anda tahu persis apa harapan untuk pengujian di perusahaan Anda. Akan ada proyek lain dan Anda akan dapat membedakan masalah dengan pengujian proyek saat ini vs DI.

Jika Anda tidak menggunakan DI, Anda bisa berkreasi dan membuat kode Anda DI- "siap". Gunakan konstruktor tanpa parameter untuk memanggil konstruktor lain:

MyClassConstructor()
{
    MyClassConstructor(new Dependency)
    Property = New Dependent Property
}

MyClassConstructor(Dependency)
{
    _Dependency = Dependency
}
JLH
sumber
0

Saya pikir salah satu kekhawatiran terbesar mereka justru sebaliknya: DI tidak membuat proyek menjadi kompleks. Dalam kebanyakan kasus ini mengurangi banyak kerumitan.

Pikirkan saja tanpa DI, apa yang akan Anda dapatkan dari objek / komponen dependen yang Anda butuhkan? Biasanya itu adalah dengan mencari dari repositori, atau mendapatkan singleton, atau instantiasi diri Anda sendiri.

2 sebelumnya melibatkan kode tambahan dalam menemukan komponen dependen, di dunia DI, Anda tidak melakukan apa pun untuk melakukan pencarian. Kompleksitas komponen Anda sebenarnya berkurang.

Jika Anda membuat contoh sendiri dalam beberapa kasus yang tidak sesuai, itu bahkan menciptakan lebih banyak kompleksitas. Anda perlu tahu cara membuat objek dengan benar, Anda perlu tahu nilai apa untuk menginisialisasi objek ke keadaan bisa diterapkan, semua ini menciptakan kompleksitas tambahan untuk kode Anda.

Jadi, DI tidak membuat kompleks proyek, itu membuatnya lebih sederhana, dengan membuat komponen lebih sederhana.

Argumen besar lainnya adalah, Anda tidak akan mencolokkan implementasi yang berbeda. Ya, memang benar bahwa dalam kode produksi, tidak umum untuk memiliki banyak implementasi yang berbeda dalam kode produksi nyata. Namun ada satu tempat utama yang membutuhkan implementasi yang berbeda: Mock / Stub / Test Doubles dalam Unit Tests. Untuk membuat DI berfungsi, dalam kebanyakan kasus ini bergantung pada model pengembangan yang digerakkan oleh antarmuka, yang pada gilirannya memungkinkan model mengejek / mematikan. Selain mengganti implementasi, "desain berorientasi antarmuka" juga membuat desain lebih bersih dan lebih baik. Tentu saja Anda masih bisa mendesain dengan antarmuka tanpa DI. Namun, tes Unit dan DI mendorong Anda untuk mengadopsi praktik-praktik tersebut.

Kecuali jika "dewa" Anda di perusahaan berpikir bahwa: "kode sederhana", "tes unit", "modularisasi", "tanggung jawab tunggal", dll. Adalah sesuatu yang mereka lawan, seharusnya tidak ada alasan bagi mereka untuk menolak menggunakan DI.

Adrian Shum
sumber
Itu bagus secara teori, tetapi dalam praktiknya menambahkan wadah DI ADALAH kompleksitas tambahan. Bagian kedua dari argumen Anda menunjukkan mengapa itu layak untuk dikerjakan, tetapi masih berfungsi.
schlingel
Sebenarnya dari pengalaman masa lalu saya, DI MENGURANGI bukannya menambah kompleksitas. Ya itu memiliki beberapa tambahan yang ditambahkan ke sistem, yang berkontribusi terhadap kompleksitas. Namun dengan DI, kompleksitas komponen lain dalam sistem sangat berkurang. Pada akhirnya, kompleksitas sebenarnya berkurang. Untuk bagian kedua, kecuali mereka tidak melakukan tes unit apa pun, itu BUKAN pekerjaan tambahan. Tanpa DI, unit test mereka sebagian besar akan sulit untuk ditulis dan dipelihara. Dengan DI, upaya ini sangat berkurang. Jadi, sebenarnya MENURUNKAN pekerjaan (kecuali jika tidak dan tidak mempercayai unit test)
Adrian Shum
Saya harus menekankan satu hal: DI dalam tanggapan saya tidak berarti kerangka kerja DI yang ada. Ini hanya metodologi dalam merancang / mengembangkan komponen di aplikasi Anda. Anda bisa mendapat banyak manfaat jika kode Anda digerakkan oleh antarmuka, komponen Anda mengharapkan dependensi untuk diinjeksi daripada melihat-lihat / dibuat. Dengan desain seperti itu, bahkan Anda sedang menulis beberapa "loader" khusus aplikasi yang melakukan pengkabelan komponen (tidak ada tujuan umum DI fw), Anda masih mendapatkan manfaat dari apa yang saya sebutkan: mengurangi kompleksitas, dan mengurangi pekerjaan dalam pengujian unit
Adrian Shum
0

"Kami ingin tetap sederhana, jika mungkin hanya memasukkan semuanya ke dalam satu perakitan. DI adalah kompleksitas yang tidak dibutuhkan tanpa manfaat".

Manfaatnya adalah desainnya yang dirancang untuk antarmuka dan memungkinkan ejekan yang mudah. Yang akibatnya memfasilitasi pengujian unit. Pengujian unit memastikan kode yang andal, modular, dan mudah dirawat. Jika bos Anda masih mempertahankannya sebagai ide yang buruk, tidak ada yang bisa Anda lakukan - praktik terbaik industri yang diterima yang mereka lawan.

Buat mereka mencoba menulis unit test dengan kerangka kerja DI dan mengejek perpustakaan, mereka akan segera belajar untuk menyukainya.

NimChimpsky
sumber
Menggandakan atau melipatgandakan jumlah kelas dalam sistem Anda sekarang adalah hal yang menurut saya berguna. Ini mirip dengan perdebatan tentang mencoba mendapatkan cakupan Tes Unit 100% dengan menulis tes tunggal per metode, atau menulis Tes Unit yang bermakna.
Andrew T Finnell
Saya tidak mengerti, Anda pikir pengujian unit adalah ide yang bagus? Jika Anda melakukannya, Anda juga mengejek benda juga? Ini lebih mudah dengan antarmuka dan DI. Tapi sepertinya itu yang Anda perdebatkan.
NimChimpsky
Ini benar-benar masalah ayam dan telur. Antarmuka / DI dan pengujian unit sangat erat terkait satu sama lain sehingga sulit untuk melakukan satu tanpa yang lain. Tapi saya percaya bahwa pengujian unit adalah jalan yang lebih baik dan lebih mudah untuk memulai dengan basis kode yang ada. Secara bertahap refactoring kode kludgy lama menjadi komponen yang kohesif. Setelah itu, Anda bisa berargumen bahwa pembuatan objek harus dilakukan dengan kerangka kerja DI alih-alih di newmana-mana dan menulis kelas pabrik karena Anda memiliki semua komponen ini di tempat.
Spoike
0

Apakah Anda bekerja dengan orang-orang ini pada proyek yang lebih kecil, atau hanya satu yang besar? Lebih mudah meyakinkan orang untuk mencoba sesuatu yang baru pada proyek sekunder / tersier daripada tim / perusahaan roti dan mentega. Alasan utama adalah bahwa jika gagal biaya untuk menghapus / mengganti itu jauh lebih kecil, dan itu jauh lebih sulit untuk mendapatkannya di mana-mana dalam proyek kecil. Dalam yang sudah ada besar Anda memiliki biaya dimuka yang besar untuk melakukan perubahan di mana saja sekaligus, atau periode yang diperpanjang di mana kode merupakan campuran dari pendekatan lama / baru yang menambah gesekan karena Anda harus mengingat ke arah mana setiap kelas dirancang bekerja.

Dan Neely
sumber
0

Meskipun salah satu hal yang mempromosikan DI adalah pengujian unit, tetapi saya percaya bahwa itu menambah lapisan kompleksitas dalam beberapa kasus.

  • Lebih baik memiliki mobil yang keras dalam pengujian, tetapi mudah dalam perbaikan daripada mobil yang mudah dalam pengujian dan sulit dalam perbaikan.

  • Juga nampak bagi saya bahwa kelompok yang mendorong DI hanya mempresentasikan ide-ide mereka melalui pengaruh bahwa beberapa pendekatan desain yang ada buruk.

  • jika kita memiliki metode melakukan 5 fungsi yang berbeda

    DI-People Berkata:

    • tidak ada pemisahan kekhawatiran. [apa masalahnya? mereka berusaha membuatnya tampak buruk, yang dalam logika dan pemrograman jauh lebih baik untuk mengetahui apa yang dilakukan satu sama lain dengan lebih baik untuk menghindari konflik dan harapan yang salah dan untuk melihat dampak dari perubahan kode dengan mudah, karena kami tidak dapat membuat Anda semua objek yang tidak terkait satu sama lain 100% atau setidaknya kami tidak dapat menjamin ini {kecuali mengapa pengujian regresi penting?}]
    • Kompleks [Mereka ingin mengurangi kerumitan dengan membuat tambahan lima kelas lagi masing-masing untuk menangani satu fungsi dan kelas tambahan (Kontainer) untuk membuat kelas untuk fungsi yang diperlukan sekarang berdasarkan pada pengaturan (XML atau Kamus) di samping filosofi "memiliki standar / atau tidak "diskusi, ...] lalu mereka memindahkan kompleksitas ke wadah dan ke struktur, [bagi saya sepertinya memindahkan kompleksitas dari satu tempat ke dua tempat dengan semua kompleksitas bahasa spesifik untuk menangani hal ini. ]

Saya percaya bahwa lebih baik untuk membuat pola desain kita sendiri yang sesuai dengan kebutuhan bisnis daripada dipengaruhi oleh DI.

mendukung DI, mungkin membantu dalam beberapa situasi, misalnya jika Anda memiliki ratusan implementasi untuk Antarmuka yang sama tergantung pada pemilih dan implementasi ini jauh berbeda dalam logika, dalam hal ini saya akan pergi dengan teknik serupa DI atau DI. tetapi jika kita memiliki beberapa implementasi untuk antarmuka yang sama kita tidak perlu DI.

pengguna114367
sumber