Di mana sebaiknya kode refactoring dan optimisasi cocok dalam timeline proses lincah dan air terjun?

10

Tampaknya ada pendapat ini di antara tim manajemen proyek yang menyatakan bahwa "berhasil" berarti bahwa itu harus dianggap 100% selesai. Kebanyakan programmer tahu itu tidak selalu terjadi. Jika saya mencoba pendekatan alternatif untuk membuat fungsi berfungsi, itu tidak berarti saya menemukan solusi terbaik, atau tidak akan memerlukan pengerjaan ulang setelah meninjau dengan pengembang lain. Saya akan sering menyelesaikan sesuatu, mundur, dan kemudian bertanya pada diri sendiri apa yang bisa saya lakukan dengan lebih baik setelah aturan bisnis dipenuhi. Haruskah waktu "Saya bisa berbuat lebih baik" ini benar-benar cocok di suatu tempat dalam timeline? Saya berpendapat bahwa pendekatan terbaik adalah Anda selalu meninggalkan kode lebih baik daripada ketika Anda menemukannya (pada tingkat tertentu), yang bisa berarti pasca peluncuran refactoring. Namun,


sumber

Jawaban:

13

Ada satu prinsip menyeluruh yang mengatur kebutuhan untuk memperbaiki dan mengoptimalkan, baik dalam air terjun maupun Agile: YAGNI (You Ain't Gonna Need It). Prinsip kedua adalah konsekuensi wajar dari yang pertama: "Optimalisasi prematur adalah akar dari semua kejahatan", kode yang setara dengan pepatah umum "musuh keunggulan adalah kesempurnaan".

Mari kita ambil prinsip dan menerapkannya. Anda memiliki persyaratan untuk membangun algoritma ETL yang mengambil file jenis tertentu, mengekstrak informasinya, lalu memasukkan informasi itu ke dalam basis data. Tujuan Anda untuk minggu ini (untuk tujuan kami, tidak masalah apakah Anda berada di toko Agile atau SDLC) adalah untuk menyelesaikannya.

Anda orang yang cerdas, dan Anda telah melihat sekilas gambaran besar. Anda tahu bahwa ini bukan satu-satunya jenis file yang membutuhkan proyek ETL. Jadi, Anda mempertimbangkan untuk mengimplementasikan algoritma ETL ini untuk juga bekerja pada jenis file lain, yang hanya memiliki perbedaan kecil. Melakukan ini akan melanggar YAGNI. Tugas Anda bukanlah mengembangkan algoritma untuk file lain itu; itu adalah untuk mengembangkan algoritma untuk satu file yang dibutuhkan pada akhir minggu. Untuk memenuhi tujuan itu dan lulus tes penerimaan, Anda perlu mengembangkan algoritma itu dan membuatnya bekerja dengan benar. Anda "tidak perlu" kode tambahan untuk membuatnya bekerja dengan file lain. Anda mungkin berpikir itu akan menghemat waktu Anda untuk menggabungkannya sekarang, dan Anda mungkin benar, tetapi Anda mungkin juga sangat salah; algoritme untuk file lain mungkin perlu digunakan di area sistem kode Anda tidak dapat digunakan, atau persyaratan untuk file baru mungkin berbeda dari untuk Anda dengan cara Anda tidak tahu (di Agile, mereka persyaratan mungkin belum ada). Sementara itu, Anda telah membuang-buang waktu dan tidak perlu meningkatkan kompleksitas algoritma Anda.

Sekarang, ini minggu depan, dan sebagai hadiah yang meragukan untuk pekerjaan luar biasa Anda pada algoritma pertama, Anda telah diberi tugas untuk membuat algoritma untuk dua jenis file baru. Sekarang, Anda perlu kode tambahan untuk membuat algoritma Anda bekerja dengan lebih banyak file. Anda dapat memperluas algoritme yang ada dengan menggunakan pola metode templat yang akan menggunakan pola dasar dengan langkah-langkah individual khusus file, atau Anda dapat memperoleh antarmuka umum dari algoritme yang ada, mengembangkan dua yang baru yang mengikuti antarmuka, dan menyambungkannya ke sebuah objek yang dapat memilih algoritma mana yang akan digunakan.

Saat mengembangkan, Anda tahu Anda memiliki persyaratan agar sistem dapat memproses 10KB data mentah per detik. Anda melakukan uji beban dan menemukan draf algoritma awal Anda menangani 8KB / s. Yah, itu tidak akan melewati AAT. Anda melihat dan melihat bahwa ada beberapa struktur loop kompleksitas-O (my God) dalam algoritma Anda; Anda merampingkannya dan mendapatkan 12KB / dtk. "Cukup bagus", menurut Anda, "tetapi jika saya memiliki satu loop yang buruk dalam kode, apa lagi yang bisa saya hilangkan?". buzz Anda baru saja melanggar aturan "optimisasi prematur". Kode Anda berfungsi, dan melewati semua persyaratan. Anda "selesai", hingga persyaratan diperbarui agar memerlukan 15KB / dtk. Jika dan ketika itu terjadi, MAKA Anda menarik kode kembali dan mencari hal-hal untuk diperbaiki.

Ikuti proses sederhana ini sambil mengembangkan, apakah dalam Agile atau dalam SDLC tradisional: "Pada pass pertama, buat itu bekerja. Pada pass kedua, buatlah cantik. Pada pass ketiga, buat itu SOLID." Artinya, ketika Anda pertama kali membuat garis kode, buat kode itu melakukan tugasnya dengan benar dan bebas bug, tetapi jangan terlalu memperhatikan aturan desain dalam kode ini, karena untuk semua yang Anda tahu sekarang, Anda Saya tidak akan pernah menyentuh area ini lagi. Lain kali Anda mengunjungi baris kode itu, Anda hanya membuktikan diri Anda salah; ini bukan lagi bagian dari sistem. Refactor untuk keterbacaan, keringkasan kode, dan / atau prinsip KERING (Anda mungkin telah menyalin beberapa kode untuk melakukan sesuatu lima kali; refactor yang menjadi loop dan / atau pemanggilan metode). Ketiga kalinya Anda bekerja di dalam atau di sekitar baris kode itu,

KeithS
sumber
3
Memberi +1 karena O(my God)-complexityjika tidak ada yang lain, buat saya tertawa!
Joel C
+1 untuk Dapatkan berfungsi terlebih dahulu. Terlalu banyak orang mencoba untuk menulis pola dan mengoptimalkan secara prematur kelelawar.
Justin Shield
Saya menemukan ini menjadi salah satu masalah paling sulit untuk diatasi sebagai seorang programmer. Insinyur memiliki keinginan bawaan untuk bereksperimen, mengembangkan, dan memperbaiki, tetapi pada akhirnya, Anda dibayar untuk produktivitas. Apa gunanya produk yang sempurna jika Anda menghabiskan begitu banyak waktu dan / atau uang sehingga dibatalkan karena overruns?
ToddR
Saya suka pendekatan pragmatis tapi saya punya masalah dengan "Pada pass kedua, buatlah cantik": jika pass kedua adalah satu tahun kemudian dan Anda tidak perlu memastikan bahwa variabel dan nama metode bermakna dan angka ajaib diganti dengan konstanta simbolik Anda mungkin memiliki masalah untuk memahami kode tersebut. Bagaimana cara menghadapinya? "Buat itu cantik" 1 jam setelah "membuatnya bekerja" jauh lebih murah daripada "membuatnya cantik" setelah sebulan atau setelah satu tahun. Saya setuju bahwa "membuatnya cantik" ketika perubahan kode berikutnya adalah penting jika "membuatnya cantik" belum pernah dilakukan.
k3b
Di Agile / TDD, sudah pengalaman saya bahwa pass kedua biasanya terjadi segera setelah yang pertama. Di Waterfall-ish SLDCs, Anda lebih benar; fungsi cenderung ditulis sekali dan kemudian duduk di sana sampai putaran berikutnya dari persyaratan datang yang menyentuh metode itu. Jadi, beberapa praktik pengkodean yang baik perlu terjadi saat pertama kali, seperti kode dokumentasi diri, sehingga ketika Anda kembali setahun kemudian, Anda dapat mengingat apa yang dilakukan kode dan mengapa Anda menulisnya seperti itu.
KeithS
10

jika berhasil, dan telah diuji, lalu mengapa memperbaikinya?

Ini mungkin bertentangan dengan temperamen pribadi Anda sebagai seorang insinyur / programmer, tetapi jika itu berhasil, nilai bisnis apa yang ada bagi Anda untuk terus memperbaikinya? Apakah akan membuatnya lebih mudah untuk dipertahankan dari waktu ke waktu? Jika demikian, kemudian bekerja di bawah metodologi tangkas, Anda harus dapat membuat item baru dalam jaminan Anda untuk memperbaiki dan memperbaiki kode Anda yang ada, dan mereka akan diprioritaskan dengan item-item lain di jaminan. Itulah bagian dari nilai proses tangkas: tim memutuskan bersama apa yang paling penting dan apa yang akan dilakukan selanjutnya.

Tim kami juga melacak apa yang kami sebut "utang teknis", jadi jika Anda mendapatkan sesuatu yang berfungsi tetapi Anda tahu itu bisa dilakukan dengan lebih baik, Anda mencatatnya sebagai utang teknis. Kami menggunakan scrum, dan kadang-kadang Anda akan menyelesaikan semua pekerjaan dalam sprint awal (Anda harus menyelesaikan sedikit lebih awal kira-kira separuh waktu jika Anda cukup dekat dengan perkiraan), tetapi tidak memiliki cukup waktu tersisa untuk menarik yang benar-benar baru kisah pengguna, jadi kami menghabiskan waktu ekstra untuk kembali dan mengurangi hutang teknis kami. Itu tidak dilacak secara resmi seperti cerita pengguna kami di backlog kami, dan kami dapat mengerjakannya kapan saja kami punya waktu.

Ini juga lebih atau kurang panggilan penilaian di pihak Anda ketika Anda menyebut tugas "selesai"; jika Anda tidak nyaman dengan keadaan kode Anda, jangan tandai tugas selesai.

Joel C
sumber
2
Saya telah menjadi penggemar konsep "utang teknis", +1 karena mengemukakannya dalam konteks ini.
Patrick Hughes
Benar-benar lupa tentang gagasan "utang teknis"; istilah yang bagus. Tetapi, saya diajari bahwa segala sesuatu yang memenuhi syarat sebagai "hutang teknis", yang berarti akan memerlukan siklus pengembang yang signifikan untuk direvisi, harus dihindari; "Lakukan dengan ringan" masih berarti "lakukan dengan benar", tapi jangan "menara gading" pada kode yang mungkin sekali saja.
KeithS
5

Haruskah waktu "Saya bisa berbuat lebih baik" ini benar-benar cocok di suatu tempat dalam timeline?

Iya.

Tepat sebelum Anda mulai mengkode rilis berikutnya .

Jangan refactor berdasarkan "intuisi".

Refactor berdasarkan kisah aktual sprint berikutnya.

S.Lott
sumber
2

Jangan tandai kode sebagai 100% selesai sampai Anda puas dengan refactoring. Anda hanya harus terus mengevaluasi biaya / manfaat untuk refactoring kode karena jika Anda cukup belajar Anda akan selalu melihat cara untuk membuat kode lebih baik.

Saya menggunakan metode refactor merah hijau TDD. Jadi refactoring saya menjadi bagian dari pengembangan saya. Untuk refactoring besar seperti mengubah model yang mendasarinya atau sesuatu yang serupa saya akan meminta manajemen untuk menghabiskan waktu pertama.

Menembus
sumber
1
Kode tidak "100% selesai" sampai semua produk yang ada di dalamnya mati. Sama seperti Anda tidak "lengkap" sebagai seseorang sampai jantung Anda berhenti berdetak secara permanen; Anda akan selalu menyerap informasi baru dan diminta untuk melakukan hal-hal spesifik yang belum pernah Anda lakukan sebelumnya, atau melakukan hal yang sama dengan cara baru yang lebih efisien atau lebih murah. Demikian pula, basis kode Anda SELALU akan membutuhkan pekerjaan - fitur baru dan perbaikan lama - sampai tidak ada yang menggunakan perangkat lunak lagi.
KeithS
2

"pasca peluncuran refactoring" memiliki biaya tersembunyi dalam pengujian regresi dan waktu QA yang Anda abaikan, ditambah lagi ia menanggung biaya peluang untuk tidak mengerjakan bug yang dilaporkan serta fitur dan perubahan baru / yang diminta. TANSTAAFL

Jika itu layak dilakukan, ada baiknya membuat tugas untuk mendapatkan prioritas melalui proses normal Anda dan bukan sebagai pengecualian khusus. Lagipula, Anda adalah bagian dari sebuah tim, dan bekerja dengan tujuan yang sama serta secara sewenang-wenang memperpanjang jadwal Anda untuk mengakomodasi perbaikan kode kerja juga memengaruhi mereka.

Jadi untuk jawaban nyata: jika Anda tahu bahwa Anda ingin refactor maka jadwalkan waktu itu sebagai bagian dari tugas. Jika Anda melakukan scrum / gesit maka kotak waktu tugas pembersihan. Jika Anda adalah air terjun / spiral, maka buatlah bagian refactor dari proses untuk meninjau kode dan menerima modul.

Patrick Hughes
sumber
0

Jika saya mencoba pendekatan alternatif untuk membuat fungsi berfungsi, itu tidak berarti saya menemukan solusi terbaik,

... Dalam hal ini Anda belum selesai 100% ...

atau tidak akan memerlukan pengerjaan ulang setelah meninjau dengan pengembang lain.

Jika ulasan kode dan pengerjaan ulang berikutnya adalah bagian dari siklus pengembangan Anda, sekali lagi fitur ini tidak dilakukan sampai semua ini selesai.

Saya akan sering menyelesaikan sesuatu, mundur, dan kemudian bertanya pada diri sendiri apa yang bisa saya lakukan dengan lebih baik setelah aturan bisnis dipenuhi. Haruskah waktu "Saya bisa berbuat lebih baik" ini benar-benar cocok di suatu tempat dalam timeline?

Tergantung. Jika itu berarti refactoring, itu harus menjadi bagian dari tugas pengembangan asli. Jika itu berarti bereksperimen dengan algoritma yang berpotensi lebih baik, itu bisa menjadi tugas yang terpisah.

Saya berpendapat bahwa pendekatan terbaik adalah Anda selalu meninggalkan kode lebih baik daripada ketika Anda menemukannya (pada tingkat tertentu), yang bisa berarti pasca peluncuran refactoring. Namun, tim proyek seringkali sangat tidak nyaman dengan pendekatan ini karena sekali lagi, jika berhasil, dan telah diuji, lalu mengapa memperbaikinya?

Singkatnya, karena kode dapat rusak di banyak level.

Ini adalah satu hal yang berfungsi saat ini. Ini adalah hal yang sama sekali berbeda apakah itu bersih, dapat diperpanjang, dan dapat dipelihara dalam jangka panjang.

Untuk jawaban yang lebih terperinci, lihat utas ini .

Péter Török
sumber
0

Sejauh yang saya bisa lihat dan baca, ini adalah pertanyaan yang tidak pasti. Oleh karena itu, jawaban penghindaran seperti "YAGNI" dan tanggapan lakukan-itu-benar-pertama-kali. Faktanya adalah tidak ada tempat di Agile untuk refactoring - tapi saya berpendapat bahwa harus ada.

Jawaban terbaik sejauh ini menyebutkan utang teknis. Sayangnya, ini adalah kenyataan menyedihkan dari perangkat lunak di banyak perusahaan, di mana terburu-buru untuk menyelesaikan masalah baik dalam metodologi gesit atau tidak gesit adalah umum - tetapi di bawah Agile solusi cepat dan kotor dirasionalisasi sebagai sesuatu yang baik: "memenuhi persyaratan bisnis minimum" dan "YAGNI" (berkenaan dengan menjaga kode bersih).

Akan lebih baik jika semua orang melakukan TDD, dan akan lebih bagus jika semua pengembang melakukan refactored untuk kedua atau ketiga kalinya seperti yang disarankan oleh satu jawaban. Tapi itu tidak terjadi di dunia nyata. Pengembang dengan berbagai tingkat keterampilan hampir selalu ditemukan memiliki jalan pintas dalam mengejar solusi cepat. Sebagai akibatnya, kode tersebut meluruh ke pegunungan kode yang tidak dapat dipelihara yang membutuhkan waktu beberapa hari bagi pengembang baru untuk menguraikan, yang mengganggu produktivitas dan menunda tenggat waktu. Yang dimaksud dengan "tidak dapat dipelihara" adalah solusi salin dan rekat, 5.000 kelas baris, dll. Dan semua kode ini serta perbaikan terhadap perbaikan ini adalah inti dari bisnis! - Dalam kasus solusi aditif ini, saya berpendapat, tidak ada yang namanya YAGNI! Anda akan membutuhkan kode bersih - SELALU. Jika kodenya tidak bersih, Anda pasti tidak akan membutuhkannya - lihat ramalan yang terpenuhi dengan sendirinya? Pengembang akan berusaha keras untuk tidak menggunakan kode itu sama sekali karena terlalu menyakitkan untuk dilihat. Dan lingkaran setan itu terus berlanjut sampai seluruh bola-lumpur harus dibuang dan ditulis ulang.

Jadi saya katakan - meskipun kode refactoring tidak menjadi konsep Agile tipe ceritanya yang tepat, berbeda, layak untuk itu sendiri - kita harus meluangkan waktu untuk melakukan refactor. Beberapa toko sekarang mengharuskan tim untuk menghabiskan 20% dari sprint mereka untuk hutang teknis. Mudah-mudahan, para pendukung lincah akan mengubah pikiran mereka tentang YAGNI dan membuat tempat untuk refactoring sebagai kegiatan yang diberikan waktu yang terpisah. Dan jika mereka sudah dan saya belum pernah mendengarnya, tunjukkan di mana itu dijelaskan karena saya sangat tertarik untuk mengetahuinya.

blindcodifier9734
sumber
"Faktanya adalah tidak ada tempat di Agile untuk refactoring" - Saya tidak berpikir itu pernyataan yang benar. Dengan gesit, ada tempat untuk segala jenis pengembangan, termasuk refactoring, selama ada alasan bisnis untuk itu. Jika tidak ada kasus bisnis untuk itu, mengapa Anda melakukannya?
Bryan Oakley
Saya kira Anda ada benarnya jika agak sederhana. Secara teori, seorang pengembang dapat membuat kasus bisnis untuk memperbaiki kode jelek bahkan jika itu tidak menghasilkan perubahan fungsional, tetapi itu tidak akan hidup dengan semangat gesit - menggunakan bisnis sebagai proxy untuk membenarkan pekerjaan. Saya berpendapat bahwa aktivitas refactoring ada di luar bidang lincah - semacam aktivitas CYA jika-Anda-akan - memperbaiki kode yang tidak dapat dipertahankan sehingga tidak membebani bisnis jangka panjang dan pengembang disalahkan. Sebut saja "sprint refactoring" atau apa pun, tetapi harus ada tempat formal untuk itu.
blindcodifier9734