Saya memulai pekerjaan baru baru-baru ini di mana saya bekerja pada aplikasi yang sangat besar (15 juta loc). Dalam pekerjaan saya sebelumnya kami memiliki aplikasi yang sama besar tetapi (untuk lebih baik atau lebih buruk) kami menggunakan OSGi, yang berarti aplikasi tersebut dipecah menjadi banyak layanan Microsoft yang dapat diubah, dikompilasi, dan digunakan secara mandiri. Aplikasi baru ini hanya satu basis kode besar, mungkin dengan beberapa .dlls.
Jadi saya perlu mengubah antarmuka kelas ini, karena itulah yang diminta bos saya. Mereka awalnya menulisnya dengan beberapa asumsi yang tidak menggeneralisasi terlalu baik, dan untuk sementara waktu mereka menghindari masalah refactoring karena sangat erat. Saya mengubah antarmuka dan sekarang ada lebih dari 25.000 kesalahan. Beberapa kesalahan dalam kelas dengan nama terdengar penting seperti "XYZPriceCalculator" yang reaaallyseharusnya tidak pecah. Tetapi saya tidak dapat memulai aplikasi untuk memeriksa apakah itu berfungsi sampai semua kesalahan diselesaikan. Dan banyak dari unit test yang secara langsung merujuk antarmuka itu, atau digabungkan ke kelas dasar yang mereferensikan antarmuka itu, jadi hanya memperbaiki itu adalah tugas yang cukup besar dalam dirinya sendiri. Ditambah lagi, aku tidak benar-benar tahu bagaimana semua potongan ini cocok, jadi walaupun aku bisa memulainya, aku tidak benar-benar tahu seperti apa jadinya jika semuanya rusak.
Saya tidak pernah benar-benar menghadapi masalah seperti ini di pekerjaan terakhir saya. Apa yang saya lakukan?
sumber
Jawaban:
25000 kesalahan pada dasarnya berarti "jangan sentuh itu". Ubah kembali. Buat kelas baru yang memiliki antarmuka yang diinginkan dan perlahan-lahan pindahkan konsumen kelas ke yang baru. Bergantung pada bahasanya, Anda dapat menandai kelas lama sebagai usang, yang dapat menyebabkan semua jenis peringatan kompiler, tetapi tidak akan benar-benar merusak bangunan Anda.
Sayangnya hal-hal ini terjadi di basis kode yang lebih lama. Tidak banyak yang bisa Anda lakukan kecuali perlahan-lahan membuat segalanya lebih baik. Saat Anda membuat kelas baru, pastikan Anda mengujinya dengan benar dan membuatnya menggunakan prinsip-prinsip SOLID sehingga mereka akan lebih mudah untuk berubah di masa depan.
sumber
Bagilah dan taklukkan dengan refactoring
Seringkali, memecah perubahan yang perlu Anda lakukan menjadi langkah-langkah kecil dapat membantu karena Anda kemudian dapat melakukan sebagian besar langkah-langkah kecil dengan cara yang tidak merusak perangkat lunak sama sekali. Alat refactoring banyak membantu dengan tugas-tugas seperti itu.
Membagi
Pertama, identifikasi perubahan sekecil mungkin (dalam hal perubahan logis, bukan dalam hal perubahan LoC) yang meringkaskan perubahan yang ingin Anda capai. Terutama cobalah untuk mengisolasi langkah-langkah yang refactor murni dan dapat dilakukan dengan alat.
Menaklukkan
Untuk kasus rumit seperti milik Anda, mungkin masuk akal untuk melakukan satu refactoring kecil pada satu waktu dan kemudian membiarkan masalahnya tetap ada, sehingga semua sistem integrasi berkelanjutan dapat memverifikasi perubahan, dan mungkin tim penguji juga melihatnya. Ini memvalidasi langkah yang Anda buat.
Untuk melakukan refactoring tertentu, Anda benar-benar memerlukan dukungan alat untuk kasus di mana Anda memiliki 25.000 situs panggilan metode yang ingin Anda ubah. Mungkin pencarian-dan-ganti bekerja juga, tetapi untuk kasus kritis seperti itu, saya akan takut karenanya.
Contoh
Di C #, misalnya, dimungkinkan untuk menggunakan Resharper untuk mengubah tanda tangan suatu metode. Jika perubahannya cukup sederhana, misalnya menambahkan parameter baru, maka Anda dapat menentukan nilai mana yang harus digunakan di situs panggilan yang seharusnya memiliki kesalahan kompilasi.
Anda kemudian pada basis kode bebas kesalahan segera dan dapat menjalankan semua tes unit, yang akan berlalu, karena itu hanya refactoring.
Setelah tanda tangan metode terlihat bagus, Anda bisa pergi dan mengganti nilai yang ditambahkan Resharper sebagai argumen ke parameter yang baru diperkenalkan. Ini bukan refactoring lagi, tetapi Anda memiliki basis kode bebas kesalahan dan dapat menjalankan tes setelah setiap baris yang Anda ubah.
Terkadang itu tidak berhasil
Ini adalah pendekatan yang sangat berguna untuk kasus-kasus seperti milik Anda, di mana Anda memiliki banyak situs panggilan. Dan Anda memiliki perangkat lunak yang berfungsi sekarang, jadi dimungkinkan untuk membuat langkah refactoring kecil untuk mengubah tanda tangan sedikit saja, lalu lakukan yang lain.
Sayangnya itu tidak akan berfungsi jika perubahan tandatangan terlalu kompleks dan tidak dapat dipecah menjadi perubahan yang lebih kecil. Tetapi ini jarang terjadi; membelah masalah menjadi masalah yang lebih kecil biasanya menunjukkan bahwa adalah mungkin.
sumber
Perjelas tugas Anda dengan bos Anda untuk membantunya memahami masalah dan kebutuhan Anda sebagai pengembang perangkat lunak profesional.
Jika Anda adalah bagian dari tim, cari pengembang utama dan mintalah saran.
Semoga berhasil.
sumber
Jangan menyentuhnya. Jangan melakukan apa pun.
Sebaliknya, duduklah di kursi Anda dan berteriak "Heeeeelp !!!!!" sekeras yang Anda bisa.
Ya, tidak persis seperti itu, tetapi mintalah saran dari kolega senior Anda. Jika Anda memiliki 25.000 kesalahan, Anda tidak memperbaiki kesalahan, Anda memperbaiki apa yang menyebabkan kesalahan. Dan seorang kolega senior harus bisa memberi tahu Anda cara melakukan perubahan yang diinginkan atasan Anda tanpa melibatkan 25.000 kesalahan. Ada berbagai cara untuk melakukan ini, tetapi cara yang baik tergantung pada situasi spesifik Anda.
Dan mungkin bos memberi tahu kolega senior Anda untuk melakukan perubahan yang sama, dan mereka berkata "tidak". Karena mereka tahu apa yang akan terjadi. Itu sebabnya kamu diberi pekerjaan.
sumber
API yang dimurnikan tidak bisa diubah begitu saja. Jika Anda benar - benar perlu mengubahnya, ambil dan / atau dokumentasikan mereka sebagai usang (dengan cara apa pun yang dibolehkan bahasa) dan dokumentasikan API mana yang harus digunakan sebagai gantinya. API lama kemudian dapat dihapus secara perlahan ... mungkin sangat lambat tergantung pada anggaran waktu Anda untuk refactoring.
sumber
Evaluasi
Evaluasi apakah perubahan ini diperlukan, atau apakah Anda dapat menambahkan metode baru dan menghapus yang lain.
Meneruskan
Jika diperlukan perubahan; maka rencana migrasi diperlukan.
Langkah pertama adalah memperkenalkan metode baru dan meminta metode lama memijat argumennya sehingga dapat memanggil metode baru. Ini mungkin memerlukan pengodean keras beberapa hal; tidak apa-apa.
Ini adalah titik komit: periksa apakah semua tes lulus, komit, tekan.
Migrasi
Pekerjaan yang sibuk memigrasi semua penelepon dari metode lama ke yang baru. Syukurlah itu bisa dilakukan secara bertahap berkat forwarder.
Jadi silakan; jangan ragu untuk menggunakan alat untuk membantu (
sed
menjadi yang paling mendasar, ada yang lain).Tandai metode lama sebagai usang (dengan sedikit beralih ke metode baru); itu akan membantu Anda mengetahui apakah Anda lupa sesuatu dan akan membantu jika rekan kerja memperkenalkan panggilan ke metode lama saat Anda sedang mengerjakan ini.
Ini adalah titik komit (atau mungkin beberapa titik komit): periksa apakah semua tes lulus, komit, dorong.
Menghapus
Setelah beberapa waktu berlalu (mungkin hanya dalam sehari), cukup hapus metode yang lama.
sumber
sed
mungkin ide yang buruk ... Sesuatu yang benar-benar "memahami" bahasa dan tidak akan membuat perubahan drastis yang tidak diinginkan lebih baik..c_str()
misalnya) dan memperkenalkan argumen baru.sed
agak berfungsi, kompiler menangkap masalah setelahnya.sed
(ataued
) dapat mencukupi untuk hal semacam ini - selama Anda benar-benar meninjau perbedaan sebelum Anda berkomitmen.Jika perubahan Anda ke tanda tangan metode hanyalah perubahan nama, solusi sederhana adalah dengan menggunakan alat untuk mengotomatiskan perubahan di 25.000 kelas yang merujuk metode tersebut.
Saya berasumsi bahwa Anda baru saja mengedit kode secara manual, yang memunculkan semua kesalahan. Saya juga menganggap Anda terbiasa dengan Java (melihat referensi Anda ke OSGi), jadi misalnya di Eclipse (saya tidak tahu lingkungan pemrograman mana yang Anda gunakan, tetapi lingkungan lain memiliki alat refactoring yang serupa) Anda dapat menggunakan "Refactoring -> Ubah nama" untuk memperbarui semua referensi ke metode, yang seharusnya membuat Anda tanpa kesalahan.
Jika Anda membuat perubahan lain pada tanda tangan metode daripada hanya mengganti nama (mengubah jumlah atau jenis parameter), Anda dapat menggunakan "Refactoring -> Ubah metode tanda tangan". Namun, kemungkinan Anda harus lebih berhati-hati seperti jawaban yang disarankan. Juga, terlepas dari jenis perubahan itu mungkin masih cukup tugas melakukan semua perubahan itu di basis kode sibuk.
sumber
Di sini kontribusiku.
Anda mungkin tidak terbiasa dengan proyek dan "fitur-fiturnya". Sebelum mengetikkan satu baris kode, penting untuk mengenal proyek ini. Jadi, kembalikan perubahan Anda dan mulai dengan menganalisis kode . (Setidaknya yang terkena)
Memahami solusi yang ada memberi Anda perspektif yang lebih baik tentang ke mana Anda akan masuk. Kontekstualisasikan solusi dan kepentingannya.
Seperti yang ditunjukkan @Greg, Anda harus dapat menguji kode yang ada untuk memiliki referensi yang valid untuk dibandingkan dengan (uji regresi). Solusi Anda harus mampu menghasilkan hasil yang sama dari yang ada. Pada tahap ini, apakah Anda tidak peduli apakah hasilnya benar atau tidak . Tujuan pertama adalah untuk memperbaiki, bukan untuk memperbaiki bug. Jika solusi yang ada mengatakan "2 + 2 = 42", solusi Anda juga harus. Jika tidak ada pengecualian, Anda juga tidak boleh. Jika mengembalikan nol, Anda juga harus mengembalikan nol. Dan seterusnya. Jika tidak, Anda akan membahayakan 25k baris kode.
Ini demi kompatibilitas retro.
Mengapa? Karena saat ini, Ini adalah jaminan unik Anda untuk refactor yang sukses.
Sebuah cara untuk menjamin kompatibilitas retro sangat dibutuhkan untuk Anda. Jadi inilah tantangan pertama Anda. Pisahkan komponen untuk pengujian unit.
Perlu diingat bahwa 25k baris kode dibuat dengan asumsi hasil yang mungkin dari kode yang ada. Jika Anda tidak melanggar bagian kontrak ini, maka Anda setengah jalan menuju solusi akhir. Jika Anda melakukannya, yah: mungkin kekuatannya menyertai Anda
Setelah Anda merancang dan mengimplementasikan "kontrak" baru, ganti yang lama. Jatuhkan atau keluarkan.
Saya menyarankan untuk meninggalkan bug sendirian karena refactoring dan memperbaiki bug adalah tugas yang berbeda. Jika Anda mencoba untuk memajukan keduanya, Anda mungkin gagal pada keduanya. Anda mungkin berpikir Anda menemukan bug, namun, mereka bisa jadi "fitur". Jadi biarkan mereka sendiri (sebentar).
Bagi saya, 25k baris kode cukup masalah untuk membuat saya fokus hanya pada satu tugas.
Setelah tugas pertama Anda selesai. Paparkan bug / fitur itu kepada bos Anda.
Akhirnya, seperti yang dikatakan @Stephen:
sumber
Menguji.
Semua orang merekomendasikan cara melakukan refactor sehingga dampaknya kecil. Tetapi dengan banyak kesalahan, bahkan jika Anda berhasil melakukan refactoring dengan hanya 10 baris kode (Anda mungkin bisa), maka Anda telah memengaruhi 25.000 aliran kode , bahkan jika Anda tidak perlu menulis ulang.
Jadi, hal selanjutnya yang harus dilakukan adalah memastikan suite uji regresi Anda lulus dengan warna cerah. Dan jika Anda tidak memilikinya, maka buatlah yang akan. Menambahkan rangkaian uji regresi komprehensif ke proyek monolitik Anda terdengar membosankan tetapi merupakan cara yang bagus untuk meningkatkan kepercayaan pada kandidat rilis, serta melepaskan mereka lebih cepat jika suite tersebut diotomatisasi dengan baik.
sumber