Haruskah saya memperbaiki kode yang ditandai sebagai "jangan diubah"?


148

Saya berurusan dengan basis kode yang cukup besar dan saya diberikan beberapa bulan untuk memperbaiki kode yang ada. Proses refactor diperlukan karena kami akan segera perlu menambahkan banyak fitur baru ke produk kami dan untuk saat ini kami tidak lagi dapat menambahkan fitur apa pun tanpa merusak yang lain. Singkatnya: kode berantakan, besar, kereta, yang banyak dari kita lihat dalam karier mereka.

Selama refactoring, dari waktu ke waktu saya menjumpai kelas, metode atau baris kode yang memiliki komentar seperti

Waktu habis ditetapkan untuk memberi Modul A waktu untuk melakukan hal-hal. Jika tidak waktunya seperti ini, itu akan rusak.

atau

Jangan ubah ini. Percayalah, Anda akan merusak barang-barang.

atau

Saya tahu menggunakan setTimeout bukan praktik yang baik, tetapi dalam hal ini saya harus menggunakannya

Pertanyaan saya adalah: haruskah saya memperbaiki kode ketika saya menemukan peringatan seperti itu dari penulis (tidak, saya tidak bisa menghubungi penulis)?


157
Selamat! Anda sekarang adalah pembuat kode.

12
Anda tidak dapat memperbaikinya sampai Anda tahu apa yang seharusnya dilakukan dan apa yang sebenarnya dilakukannya (Anda perlu mengetahui yang terakhir untuk memahami konsekuensi penuh dari perubahan Anda.) Masalahnya tampaknya berada dalam sinkronisasi, dan menghilangkan masalah seperti itu. harus menjadi pekerjaan refactoring # 1, atau hal-hal hanya akan menjadi lebih buruk dengan setiap perubahan. Pertanyaan yang harus Anda tanyakan adalah bagaimana melakukannya. Ada cukup banyak ketergantungan bahasa dan platform dalam pertanyaan itu. misalnya: stackoverflow.com/questions/3099794/finding-threading-bugs
sdenham

14
Menindaklanjuti komentar @ sdenham: jika Anda belum memiliki tes unit otomatis yang menggunakan basis kode Anda, saya sarankan Anda menghabiskan waktu membuat tes unit seperti itu, daripada membuang-buang waktu pada "perburuan penyihir refactoring" dengan AFAICT tanpa tujuan yang jelas dalam pikiran. Setelah Anda memiliki serangkaian unit test yang benar-benar menggunakan basis kode Anda, Anda akan memiliki cara obyektif untuk mengetahui apakah kode Anda masih berfungsi jika / ketika Anda harus menulis ulang bitnya. Semoga berhasil.
Bob Jarvis

17
Jika penulis begitu paranoid sehingga kode akan rusak jika seseorang begitu bernafas di dekat itu, itu mungkin sudah rusak dan perilaku yang tidak terdefinisi hanya terjadi seperti yang mereka inginkan saat ini. Yang pertama khususnya terdengar seperti mereka punya kondisi balapan yang mereka kludging sehingga itu berfungsi sebagian besar waktu. sdenham benar. Cari tahu apa yang seharusnya dilakukan dan jangan menganggap itu yang sebenarnya dilakukan.
Ray

7
@ Ethan Mungkin tidak sesederhana itu. Mengubah kode dapat memecahnya dengan cara yang tidak segera terlihat. Kadang-kadang rusak lama setelah Anda lupa bahwa refactor ini bisa menyebabkannya, jadi yang Anda miliki hanyalah bug "baru" dengan penyebab misterius. Ini sangat mungkin terjadi ketika itu berkaitan dengan waktu.
Paul Brinkley

Jawaban:


225

Tampaknya Anda sedang melakukan refactoring "berjaga-jaga", tanpa tahu persis bagian mana dari basis kode secara detail akan diubah ketika pengembangan fitur baru akan berlangsung. Kalau tidak, Anda akan tahu jika ada kebutuhan nyata untuk memperbaiki modul rapuh, atau jika Anda dapat membiarkannya apa adanya.

Untuk mengatakan ini dengan lurus: Saya pikir ini adalah strategi refactoring yang gagal . Anda menginvestasikan waktu dan uang perusahaan Anda untuk sesuatu di mana tidak ada yang tahu apakah itu benar-benar akan memberikan manfaat, dan Anda berada di tepi memperburuk keadaan dengan memasukkan bug ke dalam kode kerja.

Ini strategi yang lebih baik: gunakan waktu Anda untuk

  • tambahkan tes otomatis (mungkin bukan tes unit, tetapi tes integrasi) ke modul yang berisiko. Terutama modul-modul rapuh yang Anda sebutkan akan membutuhkan test suite lengkap sebelum Anda mengubah apa pun di sana.

  • refactor hanya bit yang Anda butuhkan untuk membawa tes pada tempatnya. Cobalah untuk meminimalkan perubahan yang diperlukan. Satu-satunya pengecualian adalah ketika tes Anda mengungkapkan bug - kemudian segera memperbaikinya (dan refactor sejauh Anda perlu melakukannya dengan aman).

  • ajar kolega Anda "prinsip pramuka" (AKA "refactoring oportunistik" ), jadi ketika tim mulai menambahkan fitur baru (atau untuk memperbaiki bug), mereka harus memperbaiki dan memperbaiki persis bagian-bagian dari basis kode yang perlu mereka ubah, tidak kurang, tidak lebih.

  • dapatkan salinan buku Feather "Bekerja secara efektif dengan kode warisan" untuk tim.

Jadi ketika saatnya tiba ketika Anda tahu pasti Anda perlu mengubah dan memperbaiki modul rapuh (baik karena pengembangan fitur baru, atau karena tes yang Anda tambahkan pada langkah 1 mengungkapkan beberapa bug), maka Anda dan tim Anda siap untuk refactor modul, dan kurang lebih dengan aman mengabaikan komentar peringatan itu.

Sebagai balasan untuk beberapa komentar : bersikap adil, jika seseorang mencurigai modul dalam produk yang ada menjadi penyebab masalah secara teratur, terutama modul yang ditandai sebagai "jangan sentuh", saya setuju dengan semua kamu. Ini harus ditinjau ulang, didebug dan kemungkinan besar direaktor ulang dalam proses itu (dengan dukungan tes yang saya sebutkan, dan tidak harus dalam urutan itu). Bug adalah pembenaran yang kuat untuk perubahan, sering kali lebih kuat daripada fitur baru. Namun, ini adalah keputusan kasus per kasus. Kita harus memeriksa dengan sangat hati-hati jika benar-benar layak untuk mengubah sesuatu dalam modul yang ditandai sebagai "jangan sentuh".


70
Saya tergoda untuk menurunkan suara, tetapi saya akan menahan diri. Saya telah melihat mentalitas pada banyak proyek ini menghasilkan produk yang jauh lebih buruk. Begitu kegagalan akhirnya terjadi, mereka sering menjadi bencana besar dan jauh lebih sulit untuk diperbaiki karena penguburannya. Saya secara teratur memperbaiki lumpur yang saya lihat, dan tampaknya menyebabkan masalah terburuk sebanyak yang diperbaiki atau paling baik tidak meninggalkan masalah yang diketahui; ini secara keseluruhan merupakan nilai tambah yang besar. DAN kodenya lebih baik untuk pengembangan di masa depan. Sebuah jahitan dalam waktu menghemat sembilan, tetapi masalah yang diabaikan dapat menjadi lebih buruk.
Aaron

98
Saya berpendapat bahwa setiap kode yang ditandai dengan komentar "Waktu habis ditetapkan untuk memberikan Modul A waktu untuk melakukan hal-hal. Jika tidak waktunya seperti ini, itu akan rusak" sudah memiliki bug. Ini hanya keberuntungan dari undian bahwa bug tidak terkena.
17 dari 26

10
@ 17of26: belum tentu bug. Kadang-kadang ketika Anda bekerja dengan perpustakaan pihak ketiga Anda dipaksa untuk membuat semua jenis konsesi "keanggunan" di tujuan untuk membuatnya bekerja.
whatsisname

30
@ 17of26: jika modul yang dipertaruhkan diduga memiliki bug, menambahkan tes sebelum segala jenis refactoring bahkan lebih penting. Dan ketika tes-tes itu mengungkapkan bug, maka Anda harus mengubah modul itu, dan begitu juga legitimasi untuk segera memperbaikinya. Jika tes tidak mengungkapkan bug, lebih baik biarkan kode apa adanya.
Doc Brown

17
@ Harun: Saya tidak mengerti mengapa Anda berpikir menambahkan tes atau mengikuti prinsip pramuka akibatnya akan menurunkan kualitas produk.
Doc Brown

142

Ya, Anda harus memperbaiki kode sebelum menambahkan fitur lainnya.

Masalah dengan komentar seperti ini adalah bahwa mereka bergantung pada keadaan lingkungan tertentu di mana basis kode berjalan. Batas waktu yang diprogram pada titik tertentu mungkin benar-benar diperlukan ketika diprogram.

Tetapi ada sejumlah hal yang dapat mengubah persamaan ini: perubahan perangkat keras, perubahan OS, perubahan yang tidak terkait dalam komponen sistem lain, perubahan volume data tipikal, sebut saja. Tidak ada jaminan bahwa pada hari ini masih diperlukan, atau itu masih cukup (integritas hal yang seharusnya dilindungi mungkin telah rusak untuk waktu yang lama - tanpa tes regresi yang tepat Anda mungkin tidak akan pernah memperhatikan). Inilah sebabnya mengapa pemrograman penundaan tetap untuk memungkinkan komponen lain untuk mengakhiri hampir selalu salah dan hanya berfungsi secara tidak sengaja.

Dalam kasus Anda, Anda tidak tahu keadaan aslinya, dan Anda juga tidak bisa bertanya kepada penulis aslinya. (Mungkin Anda juga tidak memiliki pengujian regresi / integrasi yang tepat, atau Anda bisa melanjutkan dan membiarkan tes Anda memberi tahu Anda apakah Anda memecahkan sesuatu.)

Ini mungkin terlihat seperti argumen untuk tidak mengubah apa pun karena kehati-hatian; tetapi Anda mengatakan bahwa bagaimanapun juga harus ada perubahan besar, sehingga bahaya mengganggu keseimbangan halus yang dulu dicapai di tempat ini sudah ada di sana. Jauh lebih baik untuk mengacaukan gerobak apel sekarang , ketika satu-satunya hal yang Anda lakukan adalah refactoring, dan pastikan bahwa jika ada yang rusak itu adalah refactoring yang menyebabkannya, daripada menunggu sampai Anda membuat perubahan tambahan secara bersamaan dan tidak pernah yakin.


46
Jawaban terbaik di sini; Sayang sekali itu underdog. Jawaban yang diterima di atas bukanlah nasihat yang baik, terutama penekanan pada "ditakdirkan." Saya telah menghabiskan tahun terakhir bekerja pada yang terbesar (~ 10 ^ 6LOC hanya untuk bagian saya itu), warisan-est, kode mengerikan yang pernah saya lihat, dan saya biasakan untuk memperbaiki bangkai kereta yang saya lihat ketika saya punya waktu, bahkan jika itu bukan bagian dari komponen yang saya kerjakan. Melakukan hal ini, saya telah menemukan dan memperbaiki bug yang bahkan tidak diketahui oleh tim pengembang (walaupun mungkin pengguna akhir kami). Bahkan, saya diperintahkan untuk melakukannya. Produk ditingkatkan sebagai hasilnya.
Aaron

10
Saya tidak akan menyebut itu refactoring, tapi memperbaiki bug.
Paŭlo Ebermann

7
Memperbaiki desain basis kode adalah refactoring. Jika desain ulang mengungkapkan bug yang bisa diperbaiki, itu memperbaiki bug. Maksud saya adalah bahwa yang pertama sering mengarah ke yang kedua, dan yang kedua sering sangat sulit tanpa yang pertama.
Kramii

10
@ Harun Anda beruntung mendapat dukungan manajemen / pengembang dalam melakukan itu. Di sebagian besar lingkungan, bug yang dikenal dan tidak dikenal yang disebabkan oleh desain dan kode yang buruk diterima sebagai urutan alami dari berbagai hal.
Rudolf Olah

5
@nocomprende Saya berpendapat bahwa jika Anda tidak memahami sistem dengan cukup baik untuk menulis beberapa tes untuk itu, Anda tidak memiliki bisnis yang mengubah cara kerjanya.
Patrick M

61

Pertanyaan saya adalah: apakah saya harus memperbaiki kode ketika saya menemukan peringatan seperti itu dari penulis

Tidak, atau setidaknya belum. Anda menyiratkan bahwa tingkat pengujian otomatis sangat rendah. Anda perlu tes sebelum dapat melakukan refactor dengan percaya diri.

untuk saat ini kami tidak lagi dapat menambahkan fitur apa pun tanpa merusak sesuatu

Saat ini Anda perlu fokus pada peningkatan stabilitas, bukan refactoring. Anda mungkin melakukan refactoring sebagai bagian dari peningkatan stabilitas, tetapi ini adalah alat untuk mencapai tujuan Anda yang sebenarnya - basis kode yang stabil.

Sepertinya ini telah menjadi basis kode warisan, jadi Anda harus memperlakukannya sedikit berbeda.

Mulailah dengan menambahkan tes karakterisasi. Jangan khawatir tentang spek apa pun, cukup tambahkan tes yang menegaskan perilaku saat ini. Ini akan membantu mencegah pekerjaan baru dari melanggar fitur yang ada.

Setiap kali Anda memperbaiki bug, tambahkan test case yang membuktikan bahwa bug tersebut sudah diperbaiki. Ini mencegah regresi langsung.

Saat Anda menambahkan fitur baru, tambahkan setidaknya beberapa pengujian dasar bahwa fitur baru berfungsi sebagaimana dimaksud.

Mungkin mendapatkan salinan "Bekerja Efektif dengan Kode Legacy"?

Saya diberi waktu beberapa bulan untuk memperbaiki kode yang ada.

Mulailah dengan meningkatkan cakupan tes. Mulailah dengan area yang paling rusak. Mulailah dengan area yang paling banyak berubah. Kemudian setelah Anda mengidentifikasi desain yang buruk, gantilah satu per satu.

Anda hampir tidak pernah melakukan satu refactor besar, tetapi sebaliknya mengalir terus-menerus dari refactor kecil setiap minggu. Satu refactor besar memiliki risiko besar untuk memecahkan banyak hal, dan sulit untuk menguji dengan baik.


10
+1 untuk menambahkan tes karakterisasi. Ini satu-satunya cara meminimalkan regresi ketika memodifikasi kode warisan yang belum diuji. Jika tes mulai gagal setelah Anda mulai membuat perubahan, Anda dapat memeriksa apakah perilaku sebelumnya benar-benar sesuai dengan spesifikasi, atau apakah perilaku baru yang diubah itu benar.
Leo

2
Baik. Atau jika tidak ada pemeriksaan spec yang dapat digunakan apakah perilaku sebelumnya benar-benar diinginkan oleh orang-orang yang membayar atau memiliki minat pada perangkat lunak.
bdsl

Mungkin mendapatkan salinan "Bekerja Efektif dengan Kode Legacy"? Berapa minggu yang diperlukan baginya untuk membaca buku itu? Dan kapan: selama jam kerja di tempat kerja, di malam hari saat semua orang tidur?
Billal Begueradj

23

Ingat pagar GK Chesterton : jangan turun pagar yang menghalangi jalan sampai Anda mengerti mengapa itu dibangun.

Anda dapat menemukan pembuat kode dan komentar dalam pertanyaan, dan berkonsultasi dengan mereka untuk mendapatkan pemahaman. Anda dapat melihat pesan komit, utas email, atau dokumen jika ada. Kemudian Anda bisa memperbaiki fragmen yang ditandai, atau akan menuliskan pengetahuan Anda di komentar sehingga orang berikutnya yang mempertahankan kode ini dapat membuat keputusan yang lebih tepat.

Tujuan Anda adalah untuk mencapai pemahaman tentang apa yang dilakukan kode, dan mengapa kode itu ditandai dengan peringatan saat itu, dan apa yang akan terjadi jika peringatan itu diabaikan.

Sebelum itu, saya tidak akan menyentuh kode yang bertanda "jangan sentuh".


4
OP mengatakan "tidak, saya tidak bisa menghubungi penulis".
FrustratedWithFormsDesigner

5
Saya tidak bisa menghubungi penulis atau dokumentasi.
kukis

21
@kukis: Anda tidak dapat menghubungi penulis, pakar domain, dan tidak dapat menemukan email / wiki / docs / test case apa pun yang berkaitan dengan kode yang dimaksud? Nah, maka itu adalah proyek penelitian penuh dalam arkeologi perangkat lunak, bukan tugas refactoring sederhana.
9000

12
Bukan tidak biasa bahwa kodenya sudah tua dan penulis telah pergi. Jika mereka akhirnya bekerja untuk pesaing maka mendiskusikannya dapat melanggar NDA seseorang. Dalam beberapa kasus penulis tidak tersedia secara permanen: Anda tidak dapat menanyakan Phil Katz tentang PKzip karena dia meninggal bertahun-tahun yang lalu.
pjc50

2
Jika Anda mengganti "menemukan penulis" dengan "memahami masalah apa yang dipecahkan kode" maka ini adalah jawaban terbaik. Kadang-kadang bit kode ini adalah solusi paling tidak mengerikan untuk bug yang membutuhkan waktu berminggu-minggu atau berbulan-bulan untuk menemukan dan melacak dan menangani, sering kali bug yang tidak dapat ditemukan oleh unit pengujian normal. (Meskipun kadang-kadang mereka adalah hasil dari programmer yang tidak tahu apa yang mereka lakukan. Tugas pertama Anda adalah memahami yang mana)
grahamparks

6

Kode dengan komentar seperti yang Anda tunjukkan akan menjadi yang teratas dalam daftar hal-hal yang akan direaksi jika, dan hanya jika saya punya alasan untuk melakukannya . Intinya, kode itu sangat busuk, Anda bahkan menciumnya melalui komentar. Tidak ada gunanya mencoba mengacak fungsi baru apa pun ke dalam kode ini, kode tersebut harus mati segera setelah perlu diubah.

Perhatikan juga bahwa komentar tidak banyak membantu: Mereka hanya memberi peringatan dan tanpa alasan. Ya, itu adalah tanda peringatan di sekitar tangki hiu. Tetapi jika Anda ingin melakukan apa pun di sekitarnya, ada sedikit poin untuk mencoba berenang bersama hiu. Imho, Anda harus menyingkirkan hiu itu terlebih dahulu.

Yang mengatakan, Anda benar-benar membutuhkan test case yang baik sebelum Anda berani bekerja pada kode tersebut. Setelah Anda memiliki kasus uji tersebut, pastikan untuk memahami setiap perubahan kecil yang Anda lakukan, untuk memastikan bahwa Anda benar-benar tidak mengubah perilaku. Jadikan prioritas utama Anda untuk menjaga semua keanehan perilaku kode hingga Anda dapat membuktikan bahwa mereka tidak berpengaruh. Ingat, Anda berurusan dengan hiu - Anda harus sangat berhati-hati.

Jadi, dalam kasus waktu habis: Biarkan sampai Anda mengerti persis apa kode menunggu, dan kemudian perbaiki alasan mengapa waktu habis diperkenalkan sebelum Anda melanjutkan untuk menghapusnya.

Juga, pastikan bahwa atasan Anda memahami upaya apa yang sedang Anda jalani, dan mengapa itu diperlukan. Dan jika mereka mengatakan tidak, jangan lakukan itu. Anda benar-benar membutuhkan dukungan mereka dalam hal ini.


1
Kadang-kadang kode akhirnya menjadi kekacauan karena harus beroperasi dengan benar pada sampel pra-produksi silikon yang perilakunya yang sebenarnya tidak sesuai dengan dokumentasi. Tergantung pada sifat dari solusi, mengganti kode mungkin ide yang baik jika kode tidak perlu dijalankan pada chip kereta, tetapi mengubah kode tanpa tingkat analisis teknik yang akan diperlukan dari kode baru mungkin tidak baik ide.
supercat

@supercat Salah satu poin saya adalah bahwa refactoring harus mempertahankan perilaku dengan sempurna. Jika tidak mempertahankan perilaku, itu lebih dari sekadar refactoring dalam buku saya (dan sangat berbahaya saat berurusan dengan kode lawas semacam itu).
cmaster

5

Mungkin bukan ide yang baik untuk memperbaiki kode dengan peringatan seperti itu, jika semuanya berjalan dengan baik.

Tetapi jika Anda harus refactor ...

Pertama, tulis beberapa tes unit dan tes integrasi untuk menguji kondisi peringatan yang memperingatkan Anda. Cobalah untuk meniru kondisi seperti produksi sebanyak mungkin . Ini berarti mencerminkan basis data produksi ke server uji, menjalankan layanan lain yang sama pada mesin, dll ... apa pun yang dapat Anda lakukan. Kemudian cobalah refactoring Anda (pada cabang yang terisolasi, tentu saja). Kemudian jalankan pengujian Anda pada kode baru Anda untuk melihat apakah Anda bisa mendapatkan hasil yang sama dengan yang asli. Jika Anda bisa, maka mungkin OK untuk menerapkan refactoring Anda dalam produksi. Tapi bersiaplah untuk memutar kembali perubahan jika ada yang salah.


5

Saya katakan maju dan ubahlah. Percaya atau tidak, tidak setiap pembuat kode adalah jenius dan peringatan seperti ini berarti itu bisa menjadi tempat untuk perbaikan. Jika ternyata penulisnya benar, Anda dapat (megap-megap) DOKUMEN atau MENJELASKAN alasan peringatan itu.


4

Saya memperluas komentar saya menjadi sebuah jawaban karena saya pikir beberapa aspek dari masalah khusus diabaikan atau digunakan untuk menarik kesimpulan yang salah.

Pada titik ini, pertanyaan apakah refactor masih prematur (walaupun mungkin akan dijawab dengan bentuk spesifik 'ya').

Masalah utama di sini adalah bahwa (sebagaimana dicatat dalam beberapa jawaban) komentar yang Anda kutip sangat menunjukkan bahwa kode memiliki kondisi ras atau masalah konkurensi / sinkronisasi lainnya, seperti yang dibahas di sini . Ini adalah masalah yang sangat sulit, karena beberapa alasan. Pertama, seperti yang Anda temukan, perubahan yang tampaknya tidak terkait dapat memicu masalah (bug lain juga dapat memiliki efek ini, tetapi kesalahan concurrency hampir selalu terjadi.) Kedua, mereka sangat sulit untuk didiagnosis: bug sering memanifestasikan dirinya di tempat yang jauh dalam waktu atau kode dari penyebabnya, dan apa pun yang Anda lakukan untuk mendiagnosisnya dapat menyebabkannya hilang ( Heisenbugs). Ketiga, bug konkurensi sangat sulit ditemukan dalam pengujian. Sebagian, itu karena ledakan kombinatorial: itu cukup buruk untuk kode sekuensial, tetapi menambahkan interleaving yang mungkin dari eksekusi bersamaan meniupnya ke titik di mana masalah sekuensial menjadi tidak signifikan dibandingkan. Selain itu, bahkan uji kasus yang baik hanya dapat memicu masalah sesekali - Nancy Leveson menghitung bahwa salah satu bug mematikan di Therac 25terjadi di 1 dari sekitar 350 kali berjalan, tetapi jika Anda tidak tahu apa bug itu, atau bahkan ada bug, Anda tidak tahu berapa banyak pengulangan membuat tes yang efektif. Selain itu, hanya pengujian otomatis yang layak pada skala ini, dan ada kemungkinan bahwa penguji memaksakan batasan waktu halus sehingga tidak akan pernah benar-benar memicu bug (Heisenbugs lagi).

Ada beberapa alat untuk pengujian concurrency di beberapa lingkungan, seperti Helgrind untuk kode menggunakan pthreads POSIX, tetapi kami tidak tahu secara spesifik di sini. Pengujian harus dilengkapi dengan analisis statis (atau apakah itu sebaliknya?), Jika ada alat yang sesuai untuk lingkungan Anda.

Untuk menambah kesulitan, kompiler (dan bahkan prosesor, saat runtime) sering bebas mengatur ulang kode dengan cara yang kadang membuat alasan tentang keamanan utasnya sangat kontra-intuitif (mungkin kasus yang paling terkenal adalah pemeriksaan ulang). idiom kunci , meskipun beberapa lingkungan (Java, C ++ ...) telah dimodifikasi untuk memperbaikinya.)

Kode ini mungkin memiliki satu masalah sederhana yang menyebabkan semua gejala, tetapi kemungkinan besar Anda memiliki masalah sistemik yang dapat membuat rencana Anda untuk menghentikan fitur baru. Saya harap saya telah meyakinkan Anda bahwa Anda mungkin memiliki masalah serius di tangan Anda, mungkin bahkan ancaman eksistensial terhadap produk Anda, dan hal pertama yang harus dilakukan adalah mencari tahu apa yang terjadi. Jika ini mengungkapkan masalah konkurensi, saya sangat menyarankan Anda untuk memperbaikinya terlebih dahulu, bahkan sebelum Anda mengajukan pertanyaan apakah Anda harus melakukan refactoring yang lebih umum, dan sebelum Anda mencoba menambahkan lebih banyak fitur.


1
Di mana Anda melihat "kondisi ras" di komentar? Di mana itu bahkan tersirat? Anda membuat banyak sekali asumsi teknis di sini bahkan tanpa manfaat melihat kode.
Robert Harvey

2
@RobertHarvey "Waktu habis ditetapkan untuk memberi Modul A waktu untuk melakukan hal-hal." - Cukup banyak definisi kondisi balapan, dan timeout bukanlah cara yang tepat untuk menanganinya. Saya bukan satu-satunya yang menarik kesimpulan ini. Jika tidak ada masalah di sini, itu tidak masalah, tetapi penanya perlu tahu, mengingat bahwa komentar ini adalah tanda bahaya untuk sinkronisasi yang tidak ditangani dengan baik.
sdenham

3

Saya berurusan dengan basis kode yang cukup besar dan saya diberikan beberapa bulan untuk memperbaiki kode yang ada. Proses refactor diperlukan karena kami akan segera menambahkan banyak fitur baru ke produk kami [...]

Selama refactoring, dari waktu ke waktu saya menjumpai kelas, metode, atau baris kode yang memiliki komentar seperti ["jangan sentuh ini!"]

Ya, Anda harus memperbaiki bagian-bagian itu terutama . Peringatan itu ditempatkan di sana oleh penulis sebelumnya yang berarti "jangan iseng mengutak-atik hal ini, itu sangat rumit dan ada banyak interaksi yang tidak terduga". Saat perusahaan Anda berencana untuk mengembangkan perangkat lunak lebih lanjut dan menambahkan banyak fitur, mereka secara khusus menugaskan Anda untuk membersihkan barang-barang ini. Jadi Anda tidak iseng - iseng merusaknya, Anda dengan sengaja ditugasi untuk membersihkannya.

Cari tahu apa yang dilakukan modul-modul rumit itu dan pecahkan menjadi masalah yang lebih kecil (apa yang seharusnya dilakukan oleh penulis asli). Untuk mendapatkan kode yang dapat dipelihara dari kekacauan, bagian-bagian yang baik perlu di-refactored dan bagian-bagian yang buruk perlu ditulis ulang .


2

Pertanyaan ini adalah variasi lain pada debat kapan / bagaimana merestorasi dan / atau membersihkan kode dengan tanda "bagaimana mewarisi kode". Kita semua memiliki pengalaman yang berbeda dan bekerja di organisasi yang berbeda dengan tim dan budaya yang berbeda, sehingga tidak ada jawaban benar atau salah kecuali "lakukan apa yang menurut Anda perlu Anda lakukan, dan lakukan dengan cara yang tidak membuat Anda dipecat" .

Saya tidak berpikir ada banyak organisasi yang akan berbaik hati untuk memiliki proses bisnis jatuh di sisinya karena aplikasi pendukung memerlukan pembersihan kode atau refactoring.

Dalam kasus khusus ini, komentar kode menaikkan tanda bahwa mengubah bagian kode ini tidak boleh dilakukan. Jadi, jika Anda melanjutkan, dan bisnis itu jatuh pada sisinya, Anda tidak hanya tidak memiliki apa pun untuk ditunjukkan untuk mendukung tindakan Anda, sebenarnya ada artefak yang bekerja bertentangan dengan keputusan Anda.

Jadi seperti yang selalu terjadi, Anda harus melanjutkan dengan hati-hati dan membuat perubahan hanya setelah Anda memahami setiap aspek dari apa yang akan Anda ubah, dan menemukan cara untuk menguji heck out dari itu memperhatikan sangat dekat dengan kapasitas dan kinerja dan waktu karena komentar dalam kode.

Tetapi meskipun demikian, manajemen Anda perlu memahami risiko yang melekat dalam apa yang Anda lakukan dan setuju bahwa apa yang Anda lakukan memiliki nilai bisnis yang melebihi risiko dan bahwa Anda telah melakukan apa yang dapat dilakukan untuk mengurangi risiko itu.

Sekarang, mari kita semua kembali ke TODO kita sendiri dan hal-hal yang kita tahu dapat ditingkatkan dalam kreasi kode kita sendiri jika saja ada lebih banyak waktu.


1

Ya, tentu saja. Ini adalah indikasi yang jelas bahwa orang yang menulis kode ini tidak puas dengan kode tersebut dan kemungkinan menusuknya sampai mereka berhasil bekerja. Mungkin saja mereka tidak mengerti apa masalah yang sebenarnya atau, lebih buruk lagi, memahami mereka dan terlalu malas untuk memperbaikinya.

Namun, itu peringatan bahwa banyak upaya akan diperlukan untuk memperbaikinya dan bahwa perbaikan tersebut akan memiliki risiko yang terkait dengan mereka.

Idealnya, Anda bisa mengetahui apa masalahnya dan memperbaikinya dengan benar. Sebagai contoh:

Waktu habis ditetapkan untuk memberi Modul A waktu untuk melakukan hal-hal. Jika tidak waktunya seperti ini, itu akan rusak.

Ini sangat menyarankan bahwa Modul A tidak menunjukkan dengan tepat kapan siap digunakan atau ketika telah selesai diproses. Mungkin orang yang menulis ini tidak mau repot memperbaiki Modul A atau tidak bisa karena suatu alasan. Ini tampak seperti bencana yang menunggu untuk terjadi karena itu menunjukkan ketergantungan waktu yang ditangani oleh keberuntungan daripada urutan yang tepat. Jika saya melihat ini, saya sangat ingin memperbaikinya.

Jangan ubah ini. Percayalah, Anda akan merusak barang-barang.

Ini tidak memberitahumu banyak. Itu akan tergantung pada apa yang dilakukan kode. Ini bisa berarti bahwa ia memiliki apa yang tampak sebagai optimasi yang jelas, karena satu dan lain alasan, akan benar-benar memecahkan kode. Sebagai contoh, sebuah loop mungkin terjadi untuk meninggalkan variabel pada nilai tertentu yang bergantung pada sepotong kode. Atau variabel mungkin diuji di utas lain dan mengubah urutan pembaruan variabel mungkin merusak kode lainnya.

Saya tahu menggunakan setTimeout bukan praktik yang baik, tetapi dalam hal ini saya harus menggunakannya.

Ini terlihat seperti yang mudah. Anda harus dapat melihat apa yang setTimeoutsedang dilakukan dan mungkin menemukan cara yang lebih baik untuk melakukannya.

Yang mengatakan, jika perbaikan semacam ini berada di luar ruang lingkup refactor Anda, ini adalah indikasi bahwa mencoba melakukan refactor di dalam kode ini dapat secara signifikan meningkatkan cakupan upaya Anda.

Paling tidak, perhatikan baik-baik kode yang terpengaruh dan lihat apakah Anda setidaknya dapat meningkatkan komentar hingga lebih jelas menjelaskan apa masalahnya. Itu mungkin menyelamatkan orang berikutnya dari menghadapi misteri yang sama yang Anda hadapi.


2
Ada kemungkinan bahwa kondisinya telah berubah ke titik di mana masalah lama tidak ada sama sekali, dan komentar peringatan telah menjadi seperti tempat di peta lama yang mengatakan, "Ini naga." Selami dan pelajari apa situasinya, atau lihatlah bahwa itu telah masuk ke dalam sejarah.

2
Di dunia nyata, beberapa perangkat tidak memberikan indikasi kesiapan yang dapat diandalkan, melainkan menetapkan waktu belum siap maksimum. Indikasi kesiapan yang andal dan efisien memang bagus, tetapi kadang-kadang seseorang terjebak menggunakan hal-hal tanpa itu.
supercat

1
@supercat Mungkin, mungkin tidak. Kami tidak tahu dari komentar di sini. Jadi ada baiknya diselidiki untuk, jika tidak ada yang lain, meningkatkan komentar dengan spesifik.
David Schwartz

1
@DavidSchwartz: Komentar tentu bisa lebih membantu, tetapi kadang-kadang tidak jelas berapa banyak waktu yang harus dihabiskan seorang programmer mencoba memetakan semua cara yang tepat di mana perangkat gagal untuk mematuhi spesifikasinya, terutama jika tidak jelas apakah masalah yang diharapkan menjadi hal yang sementara atau permanen.
supercat

1

Penulis komentar kemungkinan besar tidak sepenuhnya memahami kode itu sendiri . Jika mereka benar-benar tahu apa yang mereka lakukan, mereka akan menulis komentar yang benar-benar bermanfaat (atau tidak memperkenalkan kondisi balap sejak awal). Sebuah komentar seperti " Percayalah padaku, kamu akan merusak barang-barang. " Bagiku menunjukkan penulis mencoba mengubah sesuatu yang menyebabkan kesalahan tak terduga yang tidak sepenuhnya mereka pahami.

Kode mungkin dikembangkan melalui menebak dan coba-coba tanpa pemahaman penuh tentang apa yang sebenarnya terjadi.

Ini berarti:

  1. Beresiko untuk mengubah kode. Perlu waktu untuk memahami, jelas, dan mungkin tidak mengikuti prinsip-prinsip desain yang baik dan mungkin memiliki efek dan ketergantungan yang tidak jelas. Kemungkinan besar itu tidak cukup diuji, dan jika tidak ada yang sepenuhnya memahami apa yang dilakukan kode maka akan sulit untuk menulis tes untuk memastikan tidak ada kesalahan atau perubahan perilaku yang diperkenalkan. Kondisi balap (seperti komentar di atas) sangat sulit - ini adalah satu tempat di mana tes unit tidak akan menyelamatkan Anda.

  2. Beresiko untuk tidak mengubah kode. Kode memiliki kemungkinan tinggi mengandung bug dan kondisi balap yang tidak jelas. Jika bug kritis ditemukan dalam kode, atau perubahan persyaratan bisnis prioritas tinggi memaksa Anda untuk mengubah kode ini dalam waktu singkat, Anda dalam masalah besar. Sekarang Anda memiliki semua masalah yang diuraikan dalam 1, tetapi di bawah tekanan waktu! Lebih jauh, "area gelap" dalam kode memiliki kecenderungan untuk menyebar dan menginfeksi bagian lain dari kode yang disentuhnya.

Komplikasi lebih lanjut: Tes unit tidak akan menyelamatkan Anda . Biasanya pendekatan yang disarankan untuk memperbaiki kode lama tersebut adalah dengan menambahkan unit atau tes integrasi terlebih dahulu, kemudian mengisolasi dan refactor. Tetapi kondisi balap tidak dapat ditangkap dengan pengujian otomatis. Satu-satunya solusi adalah duduk dan memikirkan kode sampai Anda memahaminya, dan kemudian menulis ulang untuk menghindari kondisi balap.

Ini berarti tugasnya jauh lebih menuntut daripada sekadar refactoring rutin. Anda harus menjadwalkannya sebagai tugas pengembangan nyata.

Anda mungkin dapat merangkum kode yang terpengaruh sebagai bagian dari refactoring reguler, jadi setidaknya kode berbahaya diisolasi.


-1

Pertanyaan yang akan saya tanyakan adalah mengapa seseorang menulis, JANGAN EDIT di tempat pertama.

Saya telah bekerja pada banyak kode dan beberapa di antaranya jelek dan membutuhkan banyak waktu dan upaya untuk bekerja, dalam batasan yang diberikan pada saat itu.

Saya bertaruh dalam kasus ini, ini telah terjadi dan orang yang menulis komentar menemukan bahwa seseorang mengubahnya dan kemudian harus mengulangi seluruh latihan dan mengembalikannya ke jalan semula, untuk membuat benda itu bekerja. Setelah ini, karena frustrasi geser, mereka menulis ... JANGAN EDIT.

Dengan kata lain, saya tidak ingin harus memperbaikinya lagi karena saya memiliki hal-hal yang lebih baik untuk dilakukan dalam hidup saya.

Dengan mengatakan JANGAN EDIT, adalah cara untuk mengatakan bahwa kita tahu segala sesuatu yang akan kita ketahui sekarang dan oleh karena itu di masa depan kita tidak akan pernah belajar sesuatu yang baru.

Setidaknya harus ada komentar tentang alasan tidak mengedit. Seperti mengatakan "Jangan Sentuh" ​​atau "Jangan Masuk". Kenapa tidak menyentuh pagar? Kenapa tidak masuk? Bukankah lebih baik mengatakan, "Pagar Listrik, Jangan Menyentuh!" atau "Tambang Darat! Jangan Masuk!". Maka jelas mengapa, namun Anda masih bisa masuk, tetapi setidaknya tahu konsekuensinya sebelum Anda melakukannya.

Saya juga bertaruh sistem tidak memiliki tes di sekitar kode ajaib ini dan oleh karena itu tidak ada yang dapat mengkonfirmasi bahwa kode tersebut akan berfungsi dengan benar setelah perubahan apa pun. Menempatkan tes karakterisasi di sekitar kode masalah selalu merupakan langkah pertama. Lihat "Bekerja dengan Kode Warisan" oleh Michael Feathers untuk tips tentang cara memecahkan dependensi dan mendapatkan kode yang diuji, sebelum menangani mengubah kode.

Saya pikir pada akhirnya, disingkat melihat untuk membatasi refactoring dan membiarkan produk berevolusi secara alami dan organik.


2
ini tampaknya tidak menawarkan sesuatu yang substansial atas poin yang dibuat dan dijelaskan dalam 9 jawaban sebelumnya
agas
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.