Rekomendasi untuk mengintegrasikan wadah DI / IoC ke dalam aplikasi yang ada

10

Saya sekarang dihadapkan dengan mengintegrasikan wadah inversi kontrol (IoC) ke dalam aplikasi yang sudah ada, dan saya sedang mencari beberapa rekomendasi tentang cara yang paling mudah dicapai dengan tujuan akhir untuk mengurangi kopling, sehingga meningkatkan testabilitas. Meskipun saya umumnya tidak akan mengklasifikasikan sebagian besar kelas sebagai objek dewa , masing-masing memiliki terlalu banyak tanggung jawab dan ketergantungan tersembunyi melalui statika, lajang, dan kurangnya antarmuka.

Berikut ini sedikit latar belakang beberapa tantangan yang perlu dihadapi:

  • Injeksi ketergantungan jarang digunakan
  • Metode statis berlimpah - baik sebagai metode pabrik dan pembantu
  • Lajang cukup lazim
  • Antarmuka, saat digunakan, tidak terlalu granular
  • Objek sering menarik dependensi yang tidak dibutuhkan melalui kelas dasar

Maksud kami adalah bahwa lain kali kita perlu membuat perubahan di bidang tertentu, bahwa kita mencoba untuk menghilangkan ketergantungan yang, pada kenyataannya, ada tetapi tersembunyi di balik global seperti lajang dan statika.

Saya kira itu membuat wadah IoC sekunder untuk pengenalan injeksi ketergantungan, tetapi saya berharap bahwa ada serangkaian praktik dan rekomendasi yang dapat diikuti atau dipertimbangkan yang akan membantu kita keluar dari dependensi ini.

Kaleb Pederson
sumber
3
Saya harus bertanya tentang alasan melakukan ini sekarang ... apa yang mendorong perubahan ini? Kemampuan perawatan? Skalabilitas karena akan tumbuh secara eksponensial? Pengembang bosan?
Aaron McIver
1
Saya baru-baru ini bergabung dengan perusahaan dan mencoba memperkenalkan beberapa "praktik terbaik." Tujuan utama saya adalah meningkatkan testability dan mengurangi coupling. Kita dapat dengan mudah menggunakan DI / IoC untuk kode baru dan tidak bermaksud untuk mencoba mengubah semua kode yang ada sekaligus, tetapi saya ingin rekomendasi tentang cara terbaik untuk mengubah kode yang ada menjadi lebih baik saat berikutnya kita membuat perubahan di area itu. Sejauh ini satu-satunya hal yang saya temukan online adalah sebagai berikut: code.google.com/p/autofac/wiki/ExistingApplications
Kaleb Pederson
3
Kecuali jika ada sejumlah besar unit / tes integrasi otomatis di tempat; memodifikasi infrastruktur yang ada kecuali ada masalah demi praktik terbaik meminta masalah. Bahkan jika unit / unit pengujian integrasi Anda solid, saya masih ragu.
Aaron McIver
1
@ Harun Saya harap itu tidak terdengar seperti kita melakukannya demi praktik terbaik. Kami membuat perubahan karena sulit dan lambat untuk bekerja dengan kode yang ada dan melakukannya sedikit demi sedikit karena kami sedang bekerja di bidang tersebut. Dengan senang hati, kami memiliki serangkaian uji integrasi yang masuk akal dan beberapa tes unit untuk mendukung perubahan.
Kaleb Pederson

Jawaban:

8

Untuk melakukan sesuatu seperti ini, Anda harus bekerja dalam langkah-langkah, masing-masing tidak sepele tetapi mereka dapat dicapai. Sebelum Anda mulai, Anda harus memahami bahwa Anda tidak dapat mempercepat proses ini.

  1. Tetapkan subsistem utama aplikasi dan interfaceuntuk masing-masingnya. Antarmuka ini seharusnya hanya mendefinisikan metode yang akan digunakan bagian lain dari sistem untuk berbicara dengannya. CATATAN: Anda mungkin harus mengambil lebih dari satu pass pada ini.
  2. Berikan implementasi pembungkus antarmuka yang mendelegasikan ke kode yang ada. Tujuan latihan ini adalah untuk menghindari penulisan ulang secara massal , tetapi untuk memperbaiki kode untuk menggunakan antarmuka baru - yaitu mengurangi sambungan dalam sistem Anda.
  3. Mengatur wadah IoC untuk membangun sistem menggunakan antarmuka dan implementasi yang Anda buat. Pada tahap ini Anda ingin mengurus instantiating wadah IoC sehingga dapat memunculkan aplikasi. Yaitu jika Anda berada di lingkungan servlet, pastikan Anda bisa mendapatkan / membuat wadah dengan init()metode servlet .
  4. Lakukan hal yang sama dalam setiap subsistem lagi, kali ini ketika Anda refactor, Anda mengubah implementasi rintisan Anda menjadi hal yang nyata yang pada gilirannya menggunakan antarmuka untuk berbicara dengan komponen itu.
  5. Ulangi seperlunya sampai Anda memiliki keseimbangan yang baik antara ukuran komponen dengan fungsionalitas.

Ketika Anda selesai, satu-satunya metode statis yang harus Anda miliki di sistem Anda adalah yang benar-benar berfungsi - misalnya melihat Collectionskelas atau Mathkelas. Tidak boleh ada metode statis yang mencoba mengakses komponen lain secara langsung.

Ini adalah sesuatu yang akan memakan banyak waktu, sesuai rencana. Pastikan bahwa saat Anda melakukan refactoring, Anda menjadi lebih SOLID dalam pendekatan desain Anda. Pada awalnya itu akan menyakitkan. Anda secara drastis mengubah desain aplikasi Anda secara iteratif.

Berin Loritsch
sumber
Saran yang bagus Saya merujuk orang lain ke saran di sini juga ketika membuat perubahan seperti itu: code.google.com/p/autofac/wiki/ExistingApplications
Kaleb Pederson
7

Ambil Bekerja Efektif dengan Legacy Code dan ikuti sarannya. Mulailah dengan membangun pulau-pulau kode tertutup dan secara bertahap bergerak menuju aplikasi yang lebih terstruktur dengan baik. Mencoba untuk melakukan perubahan secara massal adalah resep untuk bencana.

Michael Brown
sumber
Suka buku itu !!
Martijn Verburg
Rekomendasi yang bagus. Walaupun saya membaca setengahnya bertahun-tahun yang lalu, saya membayangkan saya akan mendapatkan lebih banyak darinya sekarang karena saya berada jauh di dalam situasi itu.
Kaleb Pederson
Ini lucu, jawaban yang dipilih pada dasarnya merangkum buku;) Tentu saja Feathers masuk ke lebih detail.
Michael Brown
5

Alasan utama untuk memperkenalkan IoC adalah decoupling modul. Masalah dengan khususnya Java adalah ikatan kuat luar biasa yang diberikan newoperator, dikombinasikan dengan itu berarti kode panggilan tahu persis modul apa yang akan digunakan.

Pabrik diperkenalkan untuk memindahkan pengetahuan ini ke tempat sentral tetapi pada akhirnya Anda masih bisa menggunakan modul-modul dalam menggunakan new/ singleton yang membuat hard binding, atau Anda membaca dalam file konfigurasi dan menggunakan refleksi / Class.forName yang rapuh saat refactoring .

Jika Anda tidak memiliki target termodulasi maka IoC tidak akan memberi Anda apa pun.

Memperkenalkan tes Unit kemungkinan besar akan mengubah ini, karena Anda perlu mengejek modul yang tidak diuji, dan cara termudah untuk menangani ini serta modul produksi aktual dengan kode yang sama adalah dengan menggunakan kerangka kerja IoC untuk menyuntikkan yang sesuai modul.


sumber