Saya memiliki basis kode besar dengan banyak lajang "anti-pola", kelas utilitas dengan metode statis, dan kelas membuat ketergantungan mereka sendiri menggunakan new
kata kunci. Itu membuat kode sangat sulit untuk diuji.
Saya ingin secara bertahap memigrasi kode ke wadah injeksi ketergantungan (dalam kasus saya ini Guice
, karena ini adalah GWT
proyek). Dari pemahaman saya tentang injeksi ketergantungan, semuanya atau tidak sama sekali. Entah semua kelas dikelola oleh Spring / Guice atau tidak ada. Karena basis kode besar, saya tidak dapat mengubah kode pada malam hari. Jadi saya perlu cara untuk melakukannya secara bertahap.
Masalahnya adalah ketika saya mulai dengan kelas yang perlu disuntikkan ke kelas lain, saya tidak bisa menggunakan yang sederhana @Inject
di kelas-kelas itu, karena kelas-kelas itu belum dikelola oleh wadah. Jadi ini menciptakan rantai panjang hingga kelas "atas" yang tidak disuntikkan di mana pun.
Satu-satunya cara saya melihat adalah membuat Injector
konteks / aplikasi tersedia secara global melalui singleton untuk saat ini, sehingga kelas-kelas lain dapat memperoleh kacang yang dikelola darinya. Tetapi itu bertentangan dengan ide penting untuk tidak mengungkapkan composition root
ke aplikasi.
Pendekatan lain adalah bottom-up: untuk memulai dengan kelas "tingkat tinggi", memasukkan mereka ke dalam wadah ketergantungan injeksi dan perlahan-lahan pindah ke kelas "lebih kecil". Tetapi kemudian saya harus menunggu lama, karena saya dapat menguji kelas-kelas yang lebih kecil yang masih tergantung pada global / statika.
Apa yang akan menjadi cara untuk mencapai migrasi bertahap seperti itu?
PS Pertanyaan Pendekatan bertahap untuk injeksi ketergantungan serupa dalam judul, tetapi tidak menjawab pertanyaan saya.
sumber
Jawaban:
Maaf
C#
adalah bahasa pilihan saya, saya bisa membacaJava
tetapi mungkin akan membantai sintaks mencoba untuk menulisnya ... Konsep yang sama berlaku antaraC#
danJava
meskipun, jadi mudah-mudahan ini akan menunjukkan langkah-langkah bagaimana Anda secara bertahap dapat memindahkan basis kode Anda menjadi lebih dapat diuji.Diberikan:
dapat dengan mudah di refactored untuk menggunakan DI, tanpa menggunakan wadah IOC - dan Anda bahkan berpotensi memecahnya menjadi beberapa langkah:
(potensial) Langkah pertama - menerima dependensi tetapi tidak ada perubahan kode panggilan (UI):
Refactor 2 (atau refactor pertama jika menerapkan wadah IOC dan segera mengubah kode panggilan):
Langkah 2 secara teknis dapat dilakukan dengan sendirinya - tetapi (berpotensi) akan menjadi lebih banyak pekerjaan - tergantung pada berapa banyak kelas yang saat ini "baru" fungsi yang Anda cari ke DI.
Pertimbangkan untuk pergi dengan langkah 1 -> langkah 2 rute - Anda dapat membuat tes unit untuk
Foo
, terlepas dariBar
. Sedangkan sebelum refactor langkah 1 itu tidak mudah dicapai tanpa menggunakan implementasi sebenarnya dari kedua kelas. Melakukan langkah 1 -> langkah 2 (daripada langkah 2 dengan segera) akan memungkinkan perubahan yang lebih kecil dari waktu ke waktu, dan Anda akan sudah memulai uji coba untuk memastikan bahwa refactor Anda berfungsi tanpa konsekuensi.sumber
Konsepnya sama apakah Anda menggunakan Java, PHP, atau bahkan C #. Pertanyaan ini ditangani dengan cukup baik oleh Gemma Anible di video YouTube ini:
https://www.youtube.com/watch?v=Jccq_Ti8Lck (PHP, maaf!)
Anda mengganti kode yang tidak dapat diuji dengan "fasad" (karena tidak ada istilah yang lebih baik) yang memanggil kode baru yang dapat diuji. Kemudian secara bertahap Anda dapat mengganti panggilan lama dengan layanan yang disuntikkan. Saya telah melakukan ini di masa lalu dan itu bekerja dengan cukup baik.
sumber