Bagaimana cara mengatasi pemrograman secara kebetulan? [Tutup]

24

Dalam buku The Pragmatic Programmer , para penulis menyebutkan pemrograman dengan konsep kebetulan . Ini menjelaskan apa itu, mengapa itu disebabkan, apa bahaya yang mungkin Anda temui dan itu dibandingkan dengan ladang ranjau darat dalam perang.

Apakah Anda pernah menonton film perang hitam putih tua? Prajurit yang lelah maju dengan hati-hati keluar dari sikat. Ada pembukaan di depan: apakah ada ranjau darat, atau apakah aman untuk dilintasi? Tidak ada indikasi bahwa itu ladang ranjau — tidak ada tanda, kawat berduri, atau kawah. Tentara itu menusuk tanah di depannya dengan bayonet dan kemenangannya, mengharapkan ledakan. Tidak ada. Jadi dia berjalan dengan susah payah melalui lapangan untuk sementara waktu, mendorong dan menusuk saat dia pergi. Akhirnya, yakin bahwa lapangan itu aman, ia berdiri tegak dan maju dengan bangga, hanya untuk dihancurkan berkeping-keping.

Penyelidikan awal prajurit untuk tambang tidak mengungkapkan apa-apa, tapi ini hanya keberuntungan. Dia dibimbing ke kesimpulan yang salah — dengan hasil yang menghancurkan.

Sebagai pengembang, kami juga bekerja di ladang ranjau. Ada ratusan jebakan yang hanya menunggu untuk menangkap kita setiap hari. Mengingat kisah prajurit itu, kita harus berhati-hati dalam menarik kesimpulan yang salah. Kita harus menghindari pemrograman secara kebetulan — mengandalkan keberuntungan dan kesuksesan tak disengaja — demi pemrograman yang sengaja ...

Tetapi saya tidak benar-benar puas dengan cara mereka menggambarkan masalah "bagaimana cara mengatasinya". Ya, Anda harus berpikir dulu sebelum menulis kode, tetapi bagaimana mempraktikkannya? Satu-satunya hal yang dapat saya pikirkan adalah dengan menambahkan fitur ke proyek open source yang ada, di mana Anda harus memiliki pengetahuan tentang "apa yang saya lakukan sekarang" dan "Bagaimana cara kerja kode lain", dan itu tidak berlaku ketika Anda sedang menulis proyek Anda sendiri.

EDIT:

ringkasan dari posting Anda:

  • Jangan menebak langkah Anda selanjutnya, buktikan itu benar
  • Unit test dan refactor sebanyak mungkin, bila perlu
  • Tambahkan fitur – compile – test sesering mungkin
  • Jika Anda tidak dapat menjelaskan kode ke noob, Anda mungkin memprogram secara kebetulan.

BTW, sulit menerima jawaban, sangat sulit. Semua jawaban sangat bagus :)

py_script
sumber
6
Ini akan membantu orang yang mungkin tidak membaca buku untuk waktu yang lama untuk memiliki tautan seperti pragprog.com/the-pragmatic-programmer/extracts/coincidence .
btilly
Kecuali jika Anda memiliki karir pemrograman yang sangat singkat (atau hanya bekerja satu orang), Anda mungkin akan menemukan kode yang anehnya diketahui dan beberapa kode berjalan kemudian, uangnya turun: itu milik Anda. Ini bukan hanya pertimbangan Open Source ...
Robbie Dee
@Robbie Dee. dapatkah Anda memperjelasnya sedikit lagi? Aku tidak mengerti kamu Memang, saya memiliki karir pemrograman yang pendek dan itulah alasan dari tag junior-programmer.
py_script
2
@py_script Saya baru saja menegaskan bahwa Anda dapat dengan mudah menemukan kode Anda sendiri bertahun-tahun kemudian (dan menjadi bingung olehnya) seperti orang lain. Jadi, jika Anda memulai dengan kebiasaan baik, ini akan membayar dividen nanti.
Robbie Dee

Jawaban:

26

Anda tidak harus berpikir ke depan, cukup jelas apa yang sudah dilakukan, dan jelaskan apa yang sedang Anda lakukan saat ini.

Subrutin harus mengatakan apa yang mereka lakukan, melakukan apa yang mereka katakan, dan tidak memiliki ketergantungan tersembunyi. Kemudian seseorang yang memanggil mereka dapat dengan mudah memberi alasan tentang apa yang akan mereka lakukan.

Hindari negara global. (Variabel, lajang, dll.) Semakin banyak keadaan yang harus Anda miliki di kepala Anda untuk memahami hal-hal apa yang dilakukan, semakin sulit untuk memahami apa yang seharusnya terjadi dan menemukan kasus tepi.

Tulis tes unit. Tes unit sangat bagus untuk menangkap perilaku kode aktual yang baru saja Anda tulis, daripada perilaku ideal yang Anda harapkan.

Persingkat siklus edit / kompilasi / pengujian Anda. Ketika Anda menambahkan sejumlah besar kode dan menguji dengan buruk, maka kemungkinan besar ia akan berperilaku berbeda dari yang Anda pikirkan. Kemudian Anda "memperbaikinya" dengan beberapa perubahan acak, dan Anda mendapatkan jawaban yang tepat untuk saat ini, tetapi tidak tahu bagaimana itu sebenarnya terjadi. Anda sekarang pemrograman secara kebetulan. Tetapi ketika Anda menambahkan 5 baris dan kemudian menguji, kemungkinan Anda mendapatkan jawaban yang benar karena itu berfungsi seperti Anda berpikir itu bekerja jauh lebih baik. Saya dapat mengatakan dari pengalaman bahwa 5 potongan masing-masing 10 baris, yang diuji secara individual, adalah binatang yang sangat berbeda dari 50 baris kode yang diuji sekaligus.

Refactor tanpa ampun. Banyak kali saya melihat refactor yang akan membuat kode saya sedikit lebih sederhana tetapi mengambil banyak pekerjaan yang tidak ingin saya lakukan. Setelah saya mulai dengan sengaja menangani refactor-refactor itu sebagai prioritas, saya mendapati bahwa itu biasanya terbayar sendiri dalam waktu sebulan. Tetapi perhatikan kuncinya, refactor yang saya fokuskan adalah yang membuat kehidupan sehari-hari menjadi lebih sederhana, dan bukan yang memenuhi estetika sewenang-wenang yang lebih baik atau lebih umum. Para refactor yang telah saya pelajari menjadi lebih berhati-hati.

Tidak satu pun dari hal-hal ini memerlukan perencanaan terlebih dahulu. Tetapi mereka semua membuatnya lebih mudah untuk memahami kode yang ada, dan karena itu membuatnya mudah untuk mengimplementasikan potongan kecil berikutnya dengan cara yang disengaja.

btilly
sumber
Terima kasih, jawaban yang sangat bagus. Saya pikir bagian tentang siklus ini sangat berharga. Bisakah Anda memberi saya contoh refactoring yang harus Anda lakukan, tetapi akan memakan waktu sangat lama untuk diterapkan dan itu mungkin membuat seseorang tidak bersemangat?
py_script
1
Saya punya banyak contoh. Dalam proyek C ++ saya membuat kelas tanpa metode stringifikasi. Setelah saya membuat itu, debugging menjadi lebih mudah dan pengembangan dipercepat. Dalam proyek Perl kami memiliki hash konfigurasi di mana setiap pengembang memiliki salinan tweak masing-masing konfigurasi baru. Menambahkan parameter konfigurasi sangat merepotkan karena Anda harus mengedit konfigurasi setiap pengembang. Saya menulis sistem template untuk hash, dan itu menjadi lebih mudah. Dalam sistem pelaporan saya menambahkan fitur untuk menunjukkan hasil antara. Perkembangan saya dipercepat, dan saya bahkan mendapat laporan bug pengguna ...
btilly
1
di mana departemen keuangan telah melacak logika saya, dan menemukan pertanyaan yang tepat di mana saya salah dan apa bug saya. (Saya secara tidak sengaja menekan baris duplikat dengan UNIONtempat yang saya butuhkan UNION ALL.) Dan seterusnya.
btilly
1
Dalam sebulan? Saya biasanya menemukan bahwa setiap kali saya menyentuh kode saya merasa harus di refactored, tetapi belum refactored, dibutuhkan waktu yang hampir sama dengan refactor.
Amy Blankenship
1
@AmyBlankenship Ya. Dalam sebulan. Terkadang di dalam konyol, kadang tidak. File konfigurasi yang saya sebutkan di atas adalah contoh "kadang tidak". Butuh beberapa hari bagi saya untuk menulis, mendokumentasikan dan menguji mesin templat baru. Kemudian tulis ulang konfigurasi yang ada untuk menggunakannya, dan menjadi jauh lebih pendek, tetapi menghasilkan struktur data yang sama persis. (Itu adalah bagian tersulit dari proyek ini.) Jadi, hari ini sia-sia, sama sekali tidak ada hasil yang terlihat. Namun upaya itu terbayar hanya dalam waktu kurang dari sebulan, tetapi telah menghasilkan bunga sejak itu.
btilly
41

Cukup banyak intinya untuk tidak menebak . Kebanyakan programmer baru melakukannya, tetapi saya pernah melihat veteran melakukannya juga, karena mereka pikir itu menghemat waktu penelitian. Sesuatu tidak berfungsi, jadi Anda menambahkan a +1atau a -1, mengubah a trueke falseatau sebaliknya, menyusun ulang beberapa pernyataan, menambah atau mengubah penundaan, mengubah prioritas utas, dan transformasi kecil lainnya, pada dasarnya menguji permutasi acak hingga berfungsi.

Itu sebagian besar berlaku untuk mengubah kode yang ada, tetapi juga merupakan faktor dalam kode baru, karena tidak ada yang benar-benar mulai dari awal. Anda selalu membangun di atas perpustakaan standar, sistem operasi, atau setidaknya arsitektur prosesor.

Dengan kata lain, Anda belum selesai sampai Anda tahu mengapa perbaikan Anda berhasil. Jalan yang Anda ambil untuk sampai ke sana tidak terlalu penting. Bahkan permutasi acak kadang-kadang dapat membantu untuk mempersempit bug yang sulit didiagnosis, selama Anda meluangkan waktu sesudahnya untuk bertanya pada diri sendiri, "Oke, mengubah true to false memperbaikinya, tetapi mengapa?"

Karl Bielefeldt
sumber
1
Poin luar biasa +1. Tidak ada yang menerapkan lebih dari perbaikan kode ...
Robbie Dee
Benar juga bagi saya. Sejujurnya ada kesulitan obyektif seperti kurangnya dokumentasi kadang-kadang. Hari ini, saya memperbaiki kode saya sedikit, dan saya sampai pada kenyataan bahwa saya tidak tahu parameter apa yang berguna, karena kurangnya dokumentasi. Kami hanya tahu itu nomor.
py_script
Aku akui. Saat menghadapi sindrom tusuk gigi leaning, akan lebih mudah untuk menumpuknya sampai berhasil daripada mengetahui berapa banyak lapisan pelolosan yang Anda
lawan
16

Komentar paling menakutkan yang pernah saya temui dalam sebuah program adalah

Jangan sentuh ini. Berhasil. Kami tidak tahu bagaimana atau mengapa, tetapi itu berhasil. 1

dan itu menakutkan hanya karena mengakui bahwa potongan kode adalah hasil pemrograman secara kebetulan .

Untuk menghindari pemrograman secara kebetulan, Anda harus dapat menjelaskan (kepada rekan kerja, diri Anda sendiri atau bebek karet ) persis apa yang dilakukan kode dan mengapa itu bekerja. Peluru untuk pemrograman secara sengaja sebagian besar membantu bergerak menuju tujuan untuk dapat menjelaskan kode.


1 Untuk konteks, komentar ini muncul dalam kode yang menangani sakelar konteks dalam OS primitif. Kode sudah diproduksi selama beberapa tahun ketika saya menemukannya.

Bart van Ingen Schenau
sumber
2
ini juga disebut pengkodean ayam voodoo c2.com/cgi/wiki?VoodooChickenCoding
minusSeven
1
Bahkan jika pembuat kode percaya itu benar, komentar semacam itu sangat tidak membantu. Kode tersebut mungkin rumit, tetapi jika Anda membaca kode tersebut, Anda mungkin berpikir kode itu lurus ke depan. Semua komentar yang dilakukan adalah meningkatkan paranoia!
Robbie Dee
3
Ini juga bisa terjadi ketika mempertahankan basis kode lama, dalam bahasa yang sebagian besar tim pengembangan saat ini tidak nyaman.
pcurry
Jadi bebek karet tidak hanya untuk debugging. Bagus ... Saya pikir kami sedang mengerjakan perusahaan yang sama, kami punya banyak komentar seperti ini: P
py_script
ada situasi di mana perbaikan hanya berfungsi karena ada kesalahan pada API, dan tidak ada perbaikan yang lebih baik dan logis. Debugging beberapa lib pihak ketiga yang dikompilasi dapat mencapai kedalaman debugging kernel Dan bahkan jika Anda menemukan masalah, setelah berjam-jam debug ada sedikit yang bisa Anda lakukan. Jadi Anda mendekati masalahnya secara berbeda. Anda mengadopsi model "kotak hitam" yang memaksa Anda memprogram secara kebetulan. Anda bermain-main dengan perilaku aneh kotak hitam dan jika Anda berhasil membuatnya bekerja seperti yang Anda inginkan, HEBAT, tambahkan komentar dengan "magic do touch" dan teruskan.
Radu Simionescu
7

Untuk programmer baru, bagian terpenting dari mengatasi ini adalah untuk benar-benar memahami apa yang mereka lakukan.

Di banyak daerah, ketika Anda tidak tahu bagaimana melakukan sesuatu, Anda hanya pergi dengan coba-coba. Coba sesuatu; jika berhasil, bagus, jika tidak, coba sesuatu yang lain.

Dalam pemrograman, terutama ketika menggunakan bahasa yang memiliki konsep perilaku tidak terdefinisi (seperti C atau C ++), pendekatan ini tidak bekerja, karena kesuksesan bukan lagi keputusan boolean. Anda dapat memiliki hal-hal yang "jenis" bekerja, yang kadang-kadang berfungsi, yang bekerja untuk beberapa input tetapi tidak untuk yang lain.

Saya kadang-kadang mengajari programmer baru, dan kecenderungan untuk mencoba mengetik hal-hal acak untuk melihat apakah itu biasa. Mereka akan mengetik garis, dan kemudian menoleh ke saya dan bertanya, "Apakah akan bekerja seperti ini?" sementara itu jelas bahwa mereka sama sekali tidak tahu apakah itu mungkin.

Yang perlu diperhatikan adalah bahwa sebagai programmer baru Anda benar-benar harus dapat menjelaskan apa yang kode Anda lakukan. Anda harus belajar membaca kode, bukan hanya menulisnya.

(Tentu saja itu berlaku untuk programmer berpengalaman juga, tapi pengalaman saya di sini sebagian besar dengan pemula yang lengkap.)

Sebastian Redl
sumber
<< Anda harus belajar membaca kode, tidak hanya menulisnya. >> Jadi, tentang pertanyaan awal saya, apakah menurut Anda itu akan membantu saya menambahkan fitur pada proyek sumber terbuka?
py_script
2

Terlalu mudah untuk membuat kode, menguji dan memperbaiki "di jalur balap". Anda memiliki beberapa fungsionalitas yang diberikan X & Y, menghasilkan Z. Tetapi bagaimana jika X rusak dan Y tidak tersedia? Bagaimana jika Anda tidak dapat menampilkan Z? Selalu ingat apa yang salah dan buat catatan untuk siklus tes.

Jadikan rutinitas Anda singkat dan deskriptif - kode terbaik hanya membutuhkan sedikit (jika ada) komentar.

Metode yang berarti, nama kelas dan variabel pergi jauh untuk membantu keterbacaan.

Jika Anda menemukan bau kode maka BERHENTI. Bau itu tidak mungkin hilang dan sedikit usaha sekarang bisa menyelamatkan Anda dari kesedihan yang sangat besar di kemudian hari.

Sertakan pengujian dalam proses pengembangan Anda. Saya akan menganjurkan penggunaan BDD daripada TDD karena memaksa Anda untuk menggambarkan apa yang ingin Anda capai daripada bergantung secara buta pada serangkaian tes yang dapat memberi Anda rasa aman yang salah.

Tahan keinginan untuk menambahkan fitur-fitur keren lainnya (kecuali itu adalah proyek kesayangan Anda sendiri). Kode tambahan apa pun perlu dirancang, ditulis, diuji, dan dipelihara. Jika tidak diperlukan oleh klien / bisnis - Anda berisiko ini menjadi sumber daya yang sangat besar.

Robbie Dee
sumber