Pemeliharaan kode: menjaga pola yang buruk ketika memperluas kode baru agar konsisten, atau tidak?

45

Saya harus memperluas modul proyek yang sudah ada. Saya tidak suka cara itu dilakukan (banyak anti-pola yang terlibat, seperti copy / paste kode). Saya tidak ingin melakukan refactor lengkap karena berbagai alasan.

Haruskah saya:

  • buat metode baru menggunakan konvensi yang ada, bahkan jika saya merasa salah, untuk menghindari kebingungan bagi pengelola berikutnya dan konsisten dengan basis kode?

atau

  • coba gunakan apa yang saya rasa lebih baik bahkan jika itu memperkenalkan pola lain dalam kode?

Precison diedit setelah jawaban pertama:

Kode yang ada tidak berantakan. Sangat mudah untuk diikuti dan dipahami. TETAPI memperkenalkan banyak kode boilerplate yang dapat dihindari dengan desain yang baik (kode yang dihasilkan mungkin menjadi lebih sulit untuk diikuti kemudian). Dalam kasus saya saat ini, modul DAO JDBC (spring template inboard) yang bagus, tapi saya sudah menemukan dilema ini dan saya sedang mencari umpan balik dev lainnya.

Saya tidak ingin refactor karena saya tidak punya waktu. Dan bahkan dengan waktu akan sulit untuk membenarkan bahwa modul yang berfungsi dengan baik perlu refactoring. Biaya refactoring akan lebih berat daripada manfaatnya. Ingat: kode tidak berantakan atau terlalu kompleks. Saya tidak dapat mengekstraksi beberapa metode di sana dan memperkenalkan kelas abstrak di sini. Ini lebih merupakan cacat dalam desain (saya pikir ekstrim 'Keep It Stupid Simple')

Jadi pertanyaannya juga dapat ditanyakan seperti itu:
Anda, sebagai pengembang, apakah Anda lebih suka mempertahankan kode membosankan bodoh yang mudah ATAU untuk memiliki beberapa pembantu yang akan melakukan kode membosankan bodoh di tempat Anda?

Kelemahan dari kemungkinan terakhir adalah bahwa Anda harus belajar beberapa hal dan mungkin Anda harus mempertahankan kode membosankan bodoh yang mudah juga sampai refactoring penuh dilakukan)

Guillaume
sumber
Pertanyaan yang sangat menarik!
Philippe
1
Mempertahankan kode bodoh yang mudah membosankan - menurut definisi mudah. Saya lebih suka memiliki kehidupan yang mudah dan pergi lebih awal setiap hari.
cepat
Ya, tapi saya terlalu malas untuk melakukan kode bodoh yang membosankan :) Saya lebih suka bekerja keras selama 2 atau 3 hari untuk membangun sesuatu yang akan melakukan bagian ini untuk saya!
Guillaume
1
Kapan kebodohan atau kebosanan menjadi mudah?
Erik Reppen
Halo Erik, kadang-kadang kode yang bisa difaktorkan lebih mudah dibaca: sudah belasan kali hal yang sama dan kodenya mudah. Anda dapat membacanya secara berturut-turut tanpa memikirkannya dan Anda dapat melakukan debug secara linier. Tidak ada kompleksitas tersembunyi.
Guillaume

Jawaban:

42

Refactoring paling baik dilakukan dalam langkah-langkah kecil, dan lebih disukai hanya jika Anda memiliki tes unit untuk menutupi kode. (Jadi, jika Anda belum memiliki tes, berusahalah untuk menulisnya terlebih dahulu, dan sampai saat itu, tetap pada refactor yang paling sederhana, paling mudah, lebih disukai otomatis. Bantuan besar dalam hal ini adalah Bekerja secara Efektif dengan Kode Legacy oleh Michael Feathers.)

Secara umum, bertujuan untuk sedikit meningkatkan kode kapan pun Anda menyentuhnya. Ikuti Boy Scout Rule ( diciptakan oleh Robert C. Martin ) dengan meninggalkan kode lebih bersih daripada yang Anda temukan. Ketika Anda menambahkan kode baru, cobalah untuk memisahkannya dari kode buruk yang ada. Misalnya jangan menguburnya di tengah metode yang panjang, alih-alih tambahkan panggilan ke metode yang terpisah dan masukkan kode baru Anda di sana. Dengan cara ini, Anda secara bertahap menumbuhkan pulau-pulau kode bersih (er) yang lebih besar dalam basis kode yang ada.

Memperbarui

Biaya refactoring akan lebih berat daripada manfaatnya. [...] Anda, sebagai pengembang, apakah Anda lebih suka mempertahankan kode membosankan yang gampang ATAU atau memiliki beberapa pembantu yang akan melakukan kode membosankan itu di tempat Anda?

Saya menekankan yang saya percaya adalah titik kunci di sini. Selalu bernilai menilai biaya dan manfaat dari refactoring sebelum kita masuk ke dalamnya. Seperti dalam kasus Anda, kebanyakan dari kita memiliki sumber daya terbatas untuk refactoring sehingga kita harus menggunakannya dengan bijak. Luangkan sedikit waktu berharga itu di refactoring di mana ia membawa manfaat paling besar dengan sedikit usaha.

Sebagai pikiran kreatif, tentu saja saya lebih suka menghasilkan kode yang sempurna, indah dan elegan, dan menulis ulang segala sesuatu yang tidak menyerupai cita-cita saya :-) Namun, pada kenyataannya, saya dibayar untuk menghasilkan perangkat lunak yang memecahkan masalah nyata bagi penggunanya, jadi saya harus berpikir tentang menghasilkan nilai paling untuk uang mereka dalam jangka panjang.

Manfaat dari refactoring hanya muncul jika ada penghematan waktu dan upaya yang cukup untuk memahami, memelihara, memperbaiki, dan memperluas kode dalam jangka panjang . Jadi jika sepotong kode - betapapun jeleknya - jarang atau tidak pernah disentuh, tidak ada bug yang diketahui di dalamnya dan saya tidak tahu adanya fitur yang akan datang dalam waktu dekat yang akan mengharuskan saya untuk menyentuhnya, saya lebih suka meninggalkannya dalam damai.

Péter Török
sumber
7
Sangat mudah untuk jatuh ke dalam perangkap 'kode sudah menyebalkan, mungkin juga membuatnya berjalan ...' Programmer yang baik tidak. Jawaban bagus.
sevenseacat
Meskipun itu kemungkinan besar pendekatan yang paling aman (kode dijamin bekerja berkat tes) itu masih menghasilkan masalah yang disebutkan dalam pertanyaan. Pola yang berbeda dimasukkan ke dalam kode. Secara umum, saya percaya Anda harus mencoba meluangkan waktu untuk memperbaiki semuanya sekaligus (ketika melakukan TDD, paling baik dengan langkah-langkah perantara) sehingga Anda tidak memiliki keadaan tidak konsisten menengah itu. Setelah selesai, komit kode Anda ke kontrol sumber.
Steven Jeuris
2
@ Seven, tidak apa-apa untuk memperbaiki semuanya sekaligus jika Anda mampu membelinya . Dalam sebagian besar proyek kehidupan nyata, Anda tidak bisa menghentikan semuanya dan menghabiskan beberapa hari atau minggu berturut-turut hanya untuk refactor. Bahkan jika Anda beruntung memiliki manajer yang mendukungnya, proyek tetap perlu dilanjutkan.
Péter Török
1
@ Seven, itu tergantung - lihat pembaruan saya di atas.
Péter Török
1
@ Péter Török: Pembaruan yang bagus! Deskripsi sempurna dari faktor dunia nyata untuk diperhitungkan.
Steven Jeuris
4

Karena Anda tidak punya waktu untuk memperbaiki dan kode dapat dipelihara, pertahankan dengan konsisten. Waktu berikutnya pastikan untuk memasukkan refactoring dalam estimasi.

kirk.burleson
sumber
3

Konsisten hanya membantu pengembang berikutnya ketika kode di sekitarnya dalam kondisi baik. Pikirkan berapa lama Anda memahami kode yang ada dan untuk menemukan "titik ekstensi" yang tepat untuk menambahkan perubahan Anda. Jika Anda mengikuti tren saat ini, maka orang berikutnya harus memahami kode yang ada serta kode baru Anda ketika dia harus membuat perubahan.

Jika Anda mengubah kode menjadi fungsi yang berarti, orang berikutnya akan lebih mudah memahami apa yang terjadi dan perlu sedikit upaya untuk menambahkan perubahannya. Pikirkan seperti ini. Anggap orang berikutnya adalah Anda. Apa yang ingin Anda lihat ketika mengunjungi kembali blok kode ini, kekacauan yang sama dengan yang Anda lihat sekarang, atau sesuatu yang lebih logis dibangun?

Michael Brown
sumber
3

Konsistensi memiliki prioritas tinggi. Jelas semua orang yang waras akan lebih suka solusi KERING yang elegan di mana-mana alih-alih platplate yang disalin di mana-mana, tetapi apakah Anda benar-benar lebih suka dua pendekatan yang berbeda dalam basis kode yang sama untuk menerapkannya secara konsisten? Bagaimana jika seseorang menemukan solusi yang lebih pintar dan juga menerapkannya secara tidak konsisten? Maka Anda memiliki tiga cara berbeda untuk melakukan hal yang sama.

Saya telah melihat banyak kode berantakan yang dihasilkan dari pengembang menemukan "cara yang lebih baik" untuk melakukan sesuatu, tetapi tidak menerapkannya secara konsisten melalui basis kode. Jika ini merupakan bagian dari strategi yang terencana dan terkoordinasi untuk menerapkan pola baru secara bertahap dari waktu ke waktu, mungkin akan berhasil, tetapi setiap pola yang diterapkan secara tidak konsisten memiliki risiko memperburuk keseluruhan sistem.

Mungkin Anda bisa mempertimbangkan refactoring dalam langkah-langkah yang lebih kecil, sehingga setiap langkah dapat diterapkan pada seluruh basis kode dalam satu langkah. Misalnya. mengekstraksi bagian yang lebih kecil dari boilerplate ke fungsi helper di setiap iterasi. Seiring waktu Anda berakhir dengan semua boilerplate di kelas pembantu. Ini mungkin terlihat sangat jelek karena tidak dirancang tetapi dikembangkan, tetapi Anda dapat memperbaikinya sekarang karena Anda memiliki semua kode di satu tempat.

JacquesB
sumber
+1 "Lalu Anda memiliki tiga cara berbeda untuk melakukan hal yang sama." Saya telah melihat ini di setiap proyek perusahaan yang saya kerjakan. Saya akan mengatakan jangan mencoba untuk memperbaiki sampai Anda telah menjelajahi kode untuk memastikan tidak ada lagi kode yang mencoba untuk mengurus kode jelek yang Anda putuskan untuk Anda refactor. Kadang-kadang yang terbaik adalah tetap dengan konvensi boilerplate, setidaknya sampai Anda telah membaca kode secara menyeluruh.
TK-421
1

Setiap refactoring yang menghilangkan kode duplikat adalah refactoring yang baik, dan tidak boleh ditunda kecuali tenggat waktu dekat. Waktu yang dihabiskan untuk refactoring satu kali, mudah diganti dengan waktu yang dimenangkan dalam implementasi di masa depan. Berkat refactoring, pekerjaan batin tidak lagi terlihat, jadi seharusnya menjadi lebih mudah dimengerti, tidak sulit untuk diikuti.

Menurut pendapat saya itu adalah kesalahpahaman umum bahwa kode refactored lebih sulit untuk diikuti. Ini biasanya merupakan argumen dari orang-orang yang hanya terbiasa dengan apa yang sedang di refactored, dan bukan hasil yang di refactored. Untuk pendatang baru, hasil refactored akan lebih jelas.

Setiap bug / fitur dapat diperbaiki / diimplementasikan di tempat sentral di lain waktu, dan secara otomatis tersedia di mana saja di aplikasi Anda. Ini adalah keuntungan besar yang biasanya sangat diremehkan. Secara umum, total refactoring komponen tidak memakan waktu lama. (berhari-hari bukannya berbulan-bulan) Ketika membandingkan ini dengan waktu yang hilang karena bug, harus memahami kode yang bisa dire-refoured, biaya refactoring menjadi minimal.

Pembaruan terkait dengan balasan Péter Török: Bukankah dengan menunda refactoring "karena butuh waktu", waktu untuk memperbaikinya di kemudian hari meningkat? Refactoring tidak akan lama, bila dilakukan lebih sering.

Bagaimana menjelaskan kepada atasan Anda bahwa Anda akan menghabiskan beberapa hari menulis kode yang tidak menambahkan apa pun pada produk, itu sulit, dan merupakan pertanyaan yang sama sekali berbeda. :)

Steven Jeuris
sumber
1
"Bagaimana menjelaskan kepada atasan Anda bahwa Anda akan menghabiskan beberapa hari menulis kode yang tidak menambah apa pun pada produk, itu sulit, dan merupakan pertanyaan yang sama sekali berbeda." Selamat mencoba ;-) Sayangnya dalam kehidupan nyata kita perlu menyelesaikan ini juga. Itu sebabnya lebih praktis untuk dilakukan dalam langkah-langkah kecil. Setengah jam refactoring dapat dilakukan sebagai bagian dari tugas dua jam, tanpa manajer Anda bahkan perlu mengetahuinya. OTOH yang menghabiskan dua hari penuh untuk refactoring jarang diketahui orang.
Péter Török
@ Péter Török: Saya sedikit memperbarui postingan ini. Tentu saja Anda masih memiliki situasi dunia nyata di mana Anda tidak diizinkan meluangkan waktu untuk refactoring. Tetapi saya sangat percaya bahwa dalam teori selalu diperoleh waktu. (kecuali Anda tahu kode yang sedang Anda kerjakan tidak akan didukung lagi dalam waktu dekat)
Steven Jeuris
seperti yang mereka katakan, dalam teori tidak ada banyak perbedaan antara praktik dan teori. Namun, dalam praktiknya ... :-) Dalam kehidupan nyata Anda mungkin tidak selalu mendapatkan kembali biaya yang dihabiskan untuk refactoring. Saya memperpanjang jawaban saya tentang ini.
Péter Török
1
Refactoring yang menghapus kode duplikat tidak selalu baik; ada kemungkinan bahwa dua metode mungkin identik di bawah aturan bisnis saat ini, tetapi itu bukan besok. Sebagai contoh, AcmeLockerBankseseorang mungkin memiliki getRow(int itemIndex)metode yang mengembalikan index % 5dan AcmeButtonPanelmungkin memiliki metode yang sama karena baik loker dan papan tombol angka hal dengan cara yang sama; jika tidak ada bank loker hari ini yang memiliki item dengan indeks lebih dari 1000 tetapi beberapa panel tombol melakukannya, dan loker masa depan menggunakan jarak baris yang berbeda untuk indeks dalam kisaran 1000-1999 ...
supercat
1
... menambahkan perilaku tambahan ke bank loker akan mudah jika bank loker dan bank tombol memiliki getRowmetode yang berbeda , tetapi mungkin lebih sulit jika fungsinya digabungkan ke metode umum.
supercat
0

Tidak bisakah Anda membuat Interface / Kelas baru yang berfungsi sebagai Fasad atas kode lama, sambil memperkenalkan kode baru Anda dengan gaya Anda sendiri yang dapat dengan mudah diperluas?

Darren Young
sumber
0

Lakukan dengan benar ke depan. Gunakan fungsi alih-alih memotong dan menempel. Itu tidak memerlukan refactoring, tetapi memberi Anda awal fondasi untuk refactoring di masa depan.

Andy Lester
sumber
0

Anda, sebagai pengembang, apakah Anda lebih suka mempertahankan kode membosankan bodoh yang mudah ATAU atau memiliki beberapa pembantu yang akan melakukan kode membosankan bodoh di tempat Anda?

Saya tidak mengerti pertanyaan yang direvisi. Saya pikir sebagian besar orang, seperti saya, lebih suka tidak mempertahankan "kode membosankan bodoh". Saya tidak tahu apa yang Anda maksud dengan pembantu, maaf.

Poster menjawab pertanyaan mereka sendiri dengan tidak membuat perubahan besar sekarang. Pilihan bagus. Saya memiliki masalah dengan kesombongan pengembang sehingga mereka tahu apa yang terbaik untuk bisnis ini. Refactoring besar secara diam-diam ... karena Anda tahu lebih baik daripada bos Anda? Manajer yang cakap dapat menimbang manfaat.

Jika refactoring bukan pilihan maka pertanyaannya menjadi lebih banyak diskusi tentang waktu, tempat, dll yang tepat untuk melakukannya. Konsistensi sangat penting. Namun kode berumur panjang sering mendapat manfaat dari "pembaruan". Orang lain telah membahas ini ...


sumber