Apa keseimbangan yang tepat antara konsistensi kode dan peningkatan kode?

53

Baru-baru ini saya berdiskusi dengan seorang rekan mengenai gaya kode. Dia berargumen bahwa penggunaan API Anda dan pola umum yang Anda gunakan harus semirip mungkin dengan kode di sekitarnya, jika tidak dengan basis kode secara keseluruhan, sama seperti yang Anda lakukan dengan penampilan kode (brace positioning, capitalization, dll) . Sebagai contoh jika saya menambahkan metode ke kelas DAO di C # Saya akan mencoba menggunakan LINQ yang sesuai untuk membantu membuat kode saya bersih dan mudah dipelihara, bahkan jika tidak ada metode lain di kelas yang menggunakannya. Namun, kolega saya berpendapat bahwa saya tidak boleh menggunakannya dalam contoh itu karena itu akan bertentangan dengan gaya kelas yang ada dan karenanya lebih sulit untuk dipahami.

Pada awalnya saya menemukan posisinya agak ekstrem, tetapi setelah memikirkannya sebentar saya mulai mengerti maksudnya. Dengan contoh LINQ hipotetis, mungkin kelas ini tidak mengandungnya karena kolega saya tidak terbiasa dengan LINQ? Jika demikian, bukankah kode saya akan lebih mudah dikelola untuk sesama pengembang jika saya tidak menggunakannya? Di sisi lain, jika saya benar-benar percaya bahwa menggunakan teknik seperti itu akan menghasilkan kode yang lebih bersih, maka bukankah seharusnya saya menggunakannya bahkan jika berbeda secara drastis dari kode di sekitarnya?

Saya berpikir bahwa inti dari argumen rekan saya adalah bahwa jika kita semua menerapkan fungsi yang sama dalam basis kode dengan cara yang berbeda, dan kita masing-masing berpikir bahwa cara kita adalah "terbaik", maka pada akhirnya kode secara keseluruhan semakin sulit untuk mengerti. Namun pada saat ini saya masih berpikir bahwa jika kita membabi buta mengikuti kode yang ada terlalu banyak maka kualitasnya akan perlahan membusuk seiring waktu.

Jadi, sejauh mana pola merupakan bagian dari gaya kode, dan di mana kita harus menarik garis antara tetap konsisten dan melakukan perbaikan?

Robert Johnson
sumber
14
Jadi bagaimana kualitas kode akan meningkat, jika semua orang membatasi diri dengan cara "buruk"?
Izkata
Ketika Anda menulis LINQ bukankah maksud Anda LINQ ke SQL? Jika ya maka saya bisa setuju dengan teman Anda. Jika Anda berbicara tentang LINQ maka saya tidak setuju dengannya. Semua orang harus terbiasa dengan LINQ hari ini. Itu bukan pilihan mereka. Mereka dibayar agar terbiasa.
Piotr Perak
@Peri yang saya maksud hanya LINQ dasar - saya kira contoh saya seharusnya tentang bekerja dengan IEnumerables daripada DAO.
Robert Johnson
2
ICYMI - Komik Dilbert tentang topik ini: dilbert.com/strips/2013-09-21
Jim Bethancourt

Jawaban:

53

Untuk memberikan jawaban yang lebih umum:

Dalam kasus seperti ini, Anda memiliki dua pemrograman "praktik terbaik" yang saling bertentangan: konsistensi kode penting, tetapi begitu juga memilih metode terbaik untuk menyelesaikan tugas Anda. Tidak ada satu jawaban yang benar untuk dilema ini; itu tergantung pada beberapa faktor:

  • Seberapa bermanfaatkah cara yang "benar"?

    • Kadang-kadang praktik terbaik yang baru dan lebih baik akan secara dramatis meningkatkan kinerja, menghilangkan bug, jauh lebih mudah diprogram, dll. Dalam kasus seperti itu, saya akan cenderung menggunakan metode baru. Di sisi lain , "cara yang benar" mungkin sedikit lebih dari gula sintaksis, atau metode idiomatis yang disepakati untuk melakukan sesuatu yang sebenarnya tidak unggul. Dalam hal ini, konsistensi kode mungkin lebih penting.
  • Seberapa besar masalah yang akan ditimbulkan oleh ketidakkonsistenan?

    • Seberapa saling terkait kode baru dengan kode lama? Apakah kode baru Anda merupakan bagian dari perpustakaan? Apakah itu membuat objek yang diteruskan ke banyak bagian dari program? Dalam kasus seperti ini, konsistensi sangat penting. Menggunakan API baru, atau cara baru dalam melakukan sesuatu secara umum, dapat menciptakan hasil yang agak berbeda yang mematahkan asumsi di tempat lain dalam program Anda. Di sisi lain , jika Anda menulis sepotong kode yang cukup terisolasi, inkonsistensi cenderung menjadi masalah.
    • Seberapa besar dan seberapa dewasa basis kode Anda? Berapa banyak pengembang yang perlu memahaminya dan mengerjakannya? Standar yang disepakati dan konsisten jauh lebih penting untuk proyek yang lebih besar.
    • Apakah kode perlu dijalankan di lingkungan yang lebih lama yang mungkin tidak mendukung fitur terbaru?

Berdasarkan keseimbangan masalah ini, Anda harus membuat pilihan yang tepat tentang rute mana yang akan diambil. Saya pribadi melihat sedikit nilai dalam konsistensi demi konsistensi, dan akan lebih suka menggunakan metode terbaru, terbaik kecuali ada biaya yang signifikan untuk melakukannya.

Tentu saja, ada opsi ketiga: menulis ulang kode yang ada sehingga menggunakan metode terbaik dan konsisten. Ada saat-saat ini diperlukan, tetapi ia datang dengan biaya tinggi.

samthebrand
sumber
7
Jawaban yang sangat bagus dan seimbang (+1). Dalam pengalaman saya, sebuah tim bisa lebih produktif jika semua setuju pada serangkaian idiom yang dipahami dengan relatif kecil daripada jika setiap anggota tim bebas untuk menggunakan idiom baru dan berbeda yang anggota tim lain mungkin merasa sulit untuk dipahami. Satu poin kecil mengenai pernyataan "menulis ulang kode yang ada sehingga menggunakan praktik terbaru dan konsisten": "terbaru" tidak secara otomatis menyiratkan "lebih baik". Seseorang harus selalu memutuskan dari kasus ke kasus.
Giorgio
1
@Iorgio, terima kasih atas umpan baliknya; Saya mengubah bahasa poin terakhir.
6
Jawaban yang bagus dan komentar yang bagus dari Giorgio. Mungkin perlu dipertimbangkan bahwa dalam contoh ini, tergantung pada tim / budaya, dimungkinkan untuk memiliki adopsi tim terkoordinasi daripada memulai sendiri. Ini mengurangi beberapa risiko di sekitar perawatan (seperti semua orang di dalamnya) (Yaitu lebih menekankan pada keterampilan aktual tim saat ini, daripada kode yang telah mereka tulis di masa lalu.)
Matt
+1. Setuju, jawaban yang menyeluruh dan seimbang - pertimbangan yang baik dari berbagai skenario. Sekali lagi, komentar baik dari Giorgio.
Robert Johnson
1
Mengenai adopsi idiom baru, teknologi: Saya akan mempertimbangkan awal proyek baru sebagai poin yang baik untuk memperkenalkan hal-hal baru. Setelah itu, selama durasi keseluruhan proyek, gaya kode harus dijaga se konsisten mungkin. Saya baru-baru ini harus menggali beberapa kode 5 tahun dan saya sangat senang bahwa saya masih bisa menemukan jalan saya melalui kode itu karena seluruh tim mematuhi arsitektur umum dan serangkaian idiom yang telah kami sepakati (bukan tanpa perjuangan! ) di awal proyek.
Giorgio
26

Tetap konsisten memiliki sedikit nilai dalam perspektif saya; terus melakukan perbaikan adalah suatu keharusan.

Posisi kolega Anda benar-benar menghambat inovasi. Argumen konsistensi membawa Anda ke dalam situasi di mana Anda dapat menggunakan, misalnya, LINQ hanya jika Anda memigrasi semua kode untuk menggunakan LINQ. Dan kita tidak punya waktu untuk ini, kan?

Saya lebih suka memiliki inkonsistensi di mana beberapa kode masih melakukan foreachlebih dari ArrayLists dan bagian lain menggunakan LINQ IEnumerable<T>, daripada tetap berpegang pada cara tertua dalam melakukan sesuatu sampai akhir waktu.

Adalah tanggung jawab kolega Anda untuk tetap relevan dan mempelajari cara-cara baru dalam melakukan sesuatu.

Joppe
sumber
3
"Adalah tanggung jawab kolega Anda untuk tetap relevan dan mempelajari cara-cara baru dalam melakukan sesuatu.": Kemungkinannya adalah menggunakan idiom dan perpustakaan baru dalam kode baru (modul baru) dan menjaga gaya konsisten dalam kode warisan.
Giorgio
8

Konsistensi API sangat penting, baik untuk API publik maupun internal.

Konsistensi pemformatan kode adalah penting, dan idealnya harus ditegakkan oleh alat pemformatan otomatis dengan aturan pemformatan yang sama untuk semua orang. Membuat hidup dengan basis kode yang dikendalikan versi bersama lebih mudah.

Konvensi penamaan harus konsisten, juga untuk hal-hal seperti variabel lokal dll.

Alat analisis statis harus digunakan untuk menegakkan konvensi dan praktik baik tertentu lainnya (tetapi jangan secara membabi buta mengikuti standar alat tersebut, standarnya terkadang dapat berbatasan dengan gila), meskipun jika sesuatu menuntutnya, jangan takut untuk menonaktifkan beberapa periksa (biasanya dengan arahan di dalam komentar) untuk sementara, jika Anda dapat membenarkannya.

Apa yang terjadi di dalam fungsi / metode , terlepas dari apa yang tercantum di atas, tidak perlu konsisten dengan cara apa pun, asalkan itu adalah kode yang baik sendiri . Kode yang baik, dapat dimengerti, dan dikomentari dengan baik sangat penting, tetapi setelah itu, jika alat analisis kompilator dan statis menganggapnya sebagai kode yang konsisten, itu cukup konsisten.


Tentang fitur bahasa baru seperti LINQ (yah, itu bukan hal yang baru), satu-satunya hal yang perlu dipertimbangkan adalah, akankah versi bahasa / perpustakaan yang cukup baru digunakan di mana- mana di mana kode akan digunakan? Jika ragu, patuhi fitur yang diketahui kompatibel. Ini tentu saja tidak mencegah Anda mendorong peningkatan versi ke seluruh sistem, sehingga Anda dapat mulai menggunakan hal-hal baik yang baru.

Dan setiap pengembang yang bekerja dengan kode harus selalu terbarui, sehingga pengembang .NET mana pun harus tahu LINQ, dan jika tidak, mereka harus dipaksa untuk belajar, demi kebaikan mereka sendiri (Anda tidak pernah tahu kapan Anda akan mencari yang baru pekerjaan di bisnis ini, karena satu dan lain hal).

Hyde
sumber
6

Jawabannya sederhana.

Konsistensi sangat penting.

tapi itu datang dengan peringatan ...

Anda dan rekan kerja Anda mungkin terobsesi dengan jenis konsistensi yang salah

Implementasi sekali pakai. Mereka dapat sepenuhnya dirombak dengan berbagai tingkat kemudahan tergantung pada kualitas dan kelengkapan dari test suite. Khawatir tentang hal-hal seperti "Haruskah ini menjadi properti?", "Bukankah seharusnya kode ini menggunakan LINQ alih-alih konstruksi tingkat yang lebih rendah?" bernilai meragukan. Sangat sulit untuk mengikat setiap pengukuran dengan nilai konsistensi pada tingkat implementasi. Pertanyaan yang jauh lebih baik untuk ditanyakan pada tingkat ini adalah "Apakah kode ini berfungsi seperti yang diiklankan?". Konsistensi implementasi TL; DR adalah tempat "pikiran kecil" memainkan hobgoblin mereka.

Mengapa konsistensi tidak sepenting di sini? Implementasi biasanya memiliki sejumlah kecil kontributor. Sebagian besar metode ditulis dan tidak pernah disentuh lagi. Dari kode yang tersisa jumlah metode yang memiliki dua kontributor hampir pasti mayoritas. Pola ini berlanjut hingga tak terhingga . Dalam konteks ini konsistensi tidak begitu penting. Jika umur simpan kode cukup kecil ( beberapa tahun ) keuntungan dari konsistensi agresif kemungkinan bukan faktor.

Ini bukan untuk mengatakan bahwa Anda harus menjadi gila dalam implementasi Anda. Alih-alih itu mengatakan bahwa desain yang bagus, bersih, sederhana akan menjadi urutan besarnya lebih berharga bagi pemelihara masa depan hipotetis Anda daripada metode konsistensi pelat ketel konyol dengan metode. Ini membawa kita ke titik nyata ...

API tidak dapat dibuang.

Ini semua level kode API, layanan web, SDK, dll. Ini harus, harus, HARUS konsisten. Keuntungan produktivitas dari variasi konsistensi ini sangat besar karena sejumlah alasan:

Tes Integrasi:

Jika Anda menjaga API Anda konsisten, Anda dapat membuat suite tes integrasi. Ini memungkinkan pengembang untuk secara bebas bertukar detail implementasi dan mencapai validasi segera. Ingin menukar kerja sama Anda dengan LINQ? Apakah tes integrasi berjalan? Ini juga memberikan validasi ketika bersiap untuk pergi ke produksi. Karena komputer cepat, satu laptop dapat membentuk karya seribu penguji yang menjalankan tugas-tugas duniawi. Ini sama saja dengan meningkatkan jumlah karyawan organisasi Anda secara signifikan.

Produktifitas

Ketika API konsisten, Anda dapat membuat perkiraan tentang cara menggunakan API hanya dengan mengikuti apa yang telah Anda pelajari tentang penggunaan bagian lain dari API. Ini karena API memberikan "tampilan dan nuansa" yang alami, konsisten. Ini berarti klien Anda menghabiskan lebih sedikit waktu untuk menyaring dokumentasi. Onboarding lebih mudah dan lebih murah. Lebih sedikit pertanyaan yang diajukan kepada orang-orang yang mengembangkan API. Konsistensi membuat semua orang menjadi pemenang

Mengapa konsistensi penting dalam skenario ini? Karena API memiliki masalah yang berlawanan dengan implementasi. Jumlah orang yang menggunakannya biasanya jauh lebih besar daripada jumlah orang yang berkontribusi pada implementasi mereka. Keuntungan kecil dari sedikit konsistensi dikalikan dan biaya mempertahankan konsistensi diamortisasi.

Kesimpulan

Konsistensi mahal. Pada wajahnya itu menurunkan produktivitas. Ini menghambat pengembang dan membuat hidup mereka lebih sulit. Ini menempatkan batasan pada cara mereka dapat memecahkan masalah kadang-kadang memaksa mereka untuk menyelesaikannya dengan cara yang tidak optimal. Ini sering karena alasan yang tidak mereka pahami, tidak dipahami, atau mereka tidak mengetahui (kontrak, kebijakan organisasi atau antar organisasi yang lebih besar).

Raymond Hettinger membuat beberapa poin bagus dalam pidatonya di Pycon 2015 tentang penggunaan panduan gaya PEP8 untuk tim pemrogram python. Dia menunjukkan bahwa obsesi pada konsistensi gaya pada potongan kode menyebabkan pengulas kode kehilangan logika serius dan kekurangan desain. Hipotesisnya dapat diringkas karena menemukan inkonsistensi gaya mudah; menentukan kualitas nyata dari sepotong kode itu sulit

Intinya di sini adalah kritis. Identifikasi di mana konsistensi penting dan lindungi secara agresif. Di mana itu tidak penting jangan buang waktu Anda. Jika Anda tidak dapat memberikan cara obyektif untuk mengukur nilai konsistensi (dalam kasus-kasus di atas "jumlah karyawan efektif", biaya sebagai fungsi produktivitas) dan Anda tidak dapat menunjukkan pengembalian yang besar, maka kemungkinan Anda melakukan tindakan merugikan untuk organisasi MU.

nsfyn55
sumber
4

Tidak terbiasa dengan LINQ? Jika demikian, bukankah kode saya akan lebih mudah dikelola untuk sesama pengembang jika saya tidak menggunakannya?

Bahasa C # masih terus berevolusi. Jika orang tidak mempelajari perubahan dari C # 1, mereka akan kehilangan:

  • Generik
  • Sebagian
  • Metode anonim
  • Iterator
  • Jenis tidak dapat dibatalkan
  • Properti otomatis
  • Jenis anonim
  • Metode penyuluhan
  • Ling
  • Lambdas
  • Metode asinkron

Ini hanyalah sejumlah kecil fitur umum yang ditemukan di artikel Wikipedia. Maksud saya adalah bahwa jika pengembang tidak belajar, basis kode akan tetap dalam ruang hampa. Orang akan berharap bahwa pengembang Anda terus meningkatkan dan basis kode berkembang, didukung oleh rangkaian uji lengkap. Apakah Anda ingat betapa buruknya dengan .NET 1 untuk mengimplementasikan properti secara manual.

Linq membuat hidup lebih mudah. Gunakan di mana Anda bisa. Anda mungkin memotivasi anggota tim Anda.

Jadi, sejauh mana pola merupakan bagian dari gaya kode, dan di mana kita harus menarik garis antara tetap konsisten dan melakukan perbaikan?

Perbaikan bertahap. Bagi saya, tidak masuk akal untuk menyimpan kode gaya lama yang kurang mudah dibaca dan berpotensi kurang terpelihara. Anggota tim Anda setidaknya harus bisa mengetahui apa yang terjadi, bahkan jika mereka tidak bisa menulisnya.

Sam
sumber
2
Saya setuju dengan sepenuh hati dengan apa yang Anda katakan, tetapi pertanyaan saya kurang tentang fitur bahasa baru dan tanggung jawab pengembang untuk mempelajarinya, melainkan pertanyaan yang lebih umum untuk memecahkan masalah serupa dengan cara yang berbeda dalam area basis kode yang relatif kecil. Saya menyebutkan LINQ karena ini adalah contoh yang baik untuk menggunakan cara berbeda dalam menyelesaikan masalah. Rekan saya senang menggunakan fitur bahasa baru, tetapi hanya jika mereka tidak bertentangan dengan butir kode yang sedang dikerjakannya.
Robert Johnson
@RobertJohnson Saya akan menunjukkan kepada kolega Anda kemudian bahwa rawatan tetap konsisten, jadi bahkan jika sesuatu "bertentangan dengan butir" kode yang ada, jika lebih dapat dikelola, Anda harus melakukannya. Saya ragu menggunakan lama tinggal DAO akan lebih mudah dikelola daripada Linq.
Andy
3

Anda harus konsisten, tetapi tidak harus dengan kode lama. Artinya, tim Anda harus menyetujui cara yang tepat dalam melakukan sesuatu, dan menggunakan cara itu setiap kali kode baru ditulis atau perubahan besar dibuat.

Dengan begitu, Anda menuai sebagian besar manfaat konsistensi (khususnya, tidak masalah siapa yang menulis kode), tetapi masih dapat meningkat jika tim melihat manfaat yang jelas dengan melakukan hal-hal dengan cara lain.

Di dunia yang ideal, kami akan menulis ulang semua kode lama agar sesuai dengan cara baru yang benar. Meskipun ini tidak layak secara ekonomi, itu harus masuk akal secara teknis (atau yang lain, cara yang baru bukanlah cara yang lebih baik), dan rencana jangka panjang Anda harus meningkatkannya. Jika itu tidak sepadan, jangan repot-repot dengan cara baru. Dengan kata lain, harus ada keuntungan yang jelas bagi cara baru untuk mempertimbangkan menyatakannya sebagai cara yang tepat.

meriton - mogok
sumber
1

Saya pikir penting untuk mengikuti gaya kode dalam proyek misalnya. konvensi penamaan, indentasi dll.

Saya tidak setuju bahwa Anda harus dibatasi menggunakan konstruksi bahasa baru atau pola desain hanya karena kolega Anda tidak memahaminya, atau mereka belum pernah digunakan dalam proyek sebelumnya.

Tentu saja hal-hal ini harus memiliki alasan yang baik untuk menggunakannya misalnya. kinerja atau singkatnya, jika sesuai.

ozz
sumber
Untuk apa minusnya?
ozz
0

Saya akan sangat berhati-hati mengikuti pola desain saat ini. Tentu saja, ketika tidak ada kelemahan yang cukup besar, kita harus selalu berusaha mengikuti pola yang sama di seluruh basis kode.

Namun, itu terlalu mudah untuk masuk ke situasi di mana mayoritas pengembang merasa seolah-olah itu "praktik terbaik" untuk mengikuti pola buruk yang ada yang mengarah ke situasi di mana pengembang yang baik menulis kode yang buruk dan tidak dapat dipelihara.

Di sisi lain, konsistensi penting. Ketika berhadapan dengan basis kode yang sangat besar, akan sangat berguna untuk mencoba mengikuti pola yang sama sehingga meskipun pengembang belum membaca setiap inci dari basis kode, mereka tahu apa yang diharapkan.

Oleh karena itu, saya percaya yang terbaik adalah membuat dan memperbarui pedoman tentang pola apa yang harus diikuti pengembang jika mampu. Dengan cara ini, setiap kode baru konsisten dengan kode baru lainnya.

pengguna606723
sumber
-1

Kami memiliki pertemuan teknis rutin, cukup informal, yang dapat dilakukan oleh siapa pun di antara kita. Jika kami menemukan teknik baru, kami akan mempresentasikannya di rapat. Anda biasanya mendapatkan perasaan yang baik tentang seberapa baik ide itu diterima dan dipahami oleh kolega Anda. Ini membantu Anda untuk memutuskan apakah bijaksana untuk memasukkannya ke dalam kode Anda, membantu orang lain untuk menguraikannya jika Anda melakukannya dan juga menetapkan orang 'pergi ke' jika orang lain membutuhkan bantuan dengan gaya itu. Jika tidak ada yang menemukan kembali roda kami masih akan menyeret barang-barang di sekitar log.

Semut
sumber
Untuk apa downvote?
Semut
Saya bukan downvoter, tapi sepertinya ini tidak tepat untuk pertanyaan. Ini adalah proses tim yang dapat diterapkan pada apa pun, bukan diskusi tentang masalah gaya pengkodean. Juga, bukankah maksud Anda "menciptakan roda" daripada "menciptakan kembali roda"?
Saya kira itu semantik apakah log adalah jenis roda atau tidak tetapi berputar, mengurangi gesekan, memiliki permukaan yang bersentuhan dengan tanah dan bulat. Saya yakin ada contoh yang lebih baik tentang apa yang saya maksud - saya akan meninggalkan itu sebagai latihan untuk pembaca.
Semut