Gaya pengkodean saat menggunakan beberapa pustaka yang berbeda

9

Saya sedang mengerjakan beberapa kode C ++ yang menggunakan beberapa pustaka, termasuk beberapa pustaka C, yang semuanya memiliki gaya pengkodean yang berbeda. Ini akan bersumber terbuka setelah mencapai tahap yang dapat digunakan. Yang akan menyebabkan kebingungan paling sedikit bagi kontributor jangka pendek yang memeriksa kode untuk memperbaiki satu bug atau menambahkan satu fitur?

  • Memiliki satu gaya pengkodean yang konsisten di seluruh aplikasi, meskipun kadang-kadang tidak cocok dengan gaya pengkodean khas perpustakaan yang digunakan.
  • Ketika perpustakaan banyak digunakan dalam modul tertentu, sesuaikan dengan gaya pengkodean khas perpustakaan itu (yaitu gaya pengkodean yang digunakan dalam kode perpustakaan sendiri dan dokumentasi) dalam modul itu.

Pemikiran saya adalah bahwa yang terakhir akan membuat lebih mudah bagi para ahli di perpustakaan tertentu untuk memberikan kontribusi satu kali, dan membuatnya lebih mudah untuk memasukkan kode tutorial / contoh selama pengembangan. Namun, itu juga membuat gaya pengkodean tidak konsisten di seluruh aplikasi. Apa pro dan kontra dari setiap pendekatan?

Karl Bielefeldt
sumber
4
Apakah mungkin untuk menghindari masalah ini dengan membungkus semua perpustakaan di abstraksi kustom Anda sendiri? Kode dan abstraksi Anda sendiri kemudian dapat mengikuti gaya pengkodean tunggal.
MetaFight
Banyak yang saya lakukan adalah mengabstraksi perpustakaan-perpustakaan itu. Pertanyaannya adalah gaya pengkodean apa yang digunakan di dalam abstraksi.
Karl Bielefeldt
6
Ah. Saya bukan ahli di sini, tetapi sepertinya Anda sebaiknya menggunakan konvensi perpustakaan itu sendiri. Menggunakan konvensi yang tidak cocok terdengar seperti mimpi buruk pemeliharaan. Dan selama gaya perpustakaan terkandung ke kelas / modul yang abstrak itu saya menganggap itu akan baik-baik saja. Sekali lagi, saya bukan pro di sini, tetapi ini sepertinya keseimbangan yang baik yang memberi Anda perawatan yang lebih mudah dalam abstraksi Anda dan juga memungkinkan Anda untuk memiliki gaya Anda sendiri di sisa aplikasi.
MetaFight
1
Terkadang abstraksi seperti itu bisa sedikit jelek, lakukan yang terbaik untuk menjaganya tetap bersih terlepas dari konvensi yang digunakan, tetapi di atas segalanya, pastikan saja API yang Anda tampilkan dari abstraksi memiliki kualitas yang cukup sehingga Anda tidak perlu kembali ke dalam campur tangan abstraksi dan konsumen akan dapat bekerja secara konsisten dengan abstraksi Anda dengan mudah untuk memastikan kode mereka tidak menjadi berantakan seperti apa yang mungkin ada di abstraksi Anda. Jadi singkatnya, tidak ada jawaban yang baik tetapi selama abstraksi Anda menyajikan API yang baik, setidaknya Anda menghentikan masalah agar tidak melewatinya.
Jimmy Hoffa
1
Apa sebenarnya yang Anda maksud dengan "gaya pengkodean" - hal-hal sederhana seperti using_underscores / camelCase / PascalCase dan lokasi penjepit, atau hal-hal yang lebih kompleks seperti tata letak kelas / metode / fungsi dan gaya imperatif / fungsional?
Izkata

Jawaban:

10

Saya pikir itu tergantung pada seberapa besar keseluruhan proyek nantinya.

Pada satu ekstrim, katakanlah Anda memiliki proyek 1 Mloc. Untuk proyek sebesar itu, tidak mungkin satu individu akan menjadi "ahli" di semua bidang yang terlibat. Jadi dalam hal ini, saya akan tetap dengan gaya kode yang ada untuk setiap komponen utama. Pengembang baru akan memilih area, mempelajarinya, dan sepertinya mereka tidak akan melihat banyak komponen lain yang mungkin memiliki gaya kode yang berbeda.

Jika proyek ini jauh lebih kecil, di mana ada kemungkinan individu memahami seluruh basis kode, maka saya akan memilih gaya kode yang dominan dan tetap menggunakannya. Dalam hal ini, saya pikir konsistensi di seluruh proyek lebih masuk akal karena pengembang baru akan cenderung bekerja di semua area proyek.

Proyek berukuran sedang mungkin yang paling sulit untuk membuat keputusan ini. Dalam hal ini, Anda harus mempertimbangkan biaya untuk setiap pendekatan dan memutuskan yang menurut Anda paling murah untuk jangka panjang. Tantangannya adalah bahwa proyek-proyek berukuran sedang biasanya hanya tumbuh cukup di mana refactoring gaya lengkap terlihat sangat mahal. Anda mungkin ingin melihat struktur pohon kode untuk melihat apakah hal-hal dapat diatur untuk mengelompokkan gaya kode tertentu bersama-sama.

Apa pun itu, keputusan akhir harus dipegang oleh tim yang Anda tuju yang menyusun paket ini.


Beberapa pencilan yang mungkin mengubah alasan saya dari atas:

  • Jika satu atau lebih modul memiliki gaya yang mengerikan, maka tidak ada gunanya mempertahankannya, bahkan pada proyek yang lebih besar. Ya, gaya itu subyektif, tetapi jika Anda dan rekan-rekan peserta proyek Anda benar-benar tidak menyukai cara daerah tertentu mengalir, maka gantikan gaya lama itu dan berikan yang lebih baik.

  • Jika semua gaya cukup dekat satu sama lain, mungkin akan lebih mudah untuk mendeklarasikan "inilah cara baru" dan menggunakannya untuk semua kode baru dan perbaikan yang signifikan. Ini dapat membuat ulasan sedikit menyakitkan, tetapi dalam pengalaman saya kebanyakan orang cukup mampu beradaptasi dengan pendekatan ini. Ini juga memberikan tanda tanda di mana kode lama berada.

  • Terkadang gaya digeser berdasarkan fungsionalitas baru yang ditambahkan ke bahasa. C ++ telah mengambil sejumlah fitur selama bertahun-tahun. Mungkin masuk akal untuk refactor sesuai kebutuhan gaya lama ke gaya baru yang memanfaatkan fitur-fitur tersebut.

  • Beberapa perpustakaan mungkin memiliki pendekatan atau gaya idiomatis. Jika demikian, saya akan tetap dengan gaya itu untuk perpustakaan itu bahkan jika itu mungkin bertentangan dengan sisa proyek. Maksudnya di sini adalah untuk meningkatkan peluang seseorang yang bekerja pada frobnosticatorsproyek lain juga akan bekerja pada proyek Anda.


Beberapa komentar menyebutkan gaya imperatif dan berorientasi objek sebagai pertimbangan.

Modul yang "berat" dengan gaya tertentu mungkin harus tetap seperti itu jika modul berukuran sedang atau lebih besar. Saya telah bekerja dengan tiga gaya utama (imperatif, objektif, dan fungsional), dan saya telah refactored gaya imperatif berat menjadi gaya OO. Dengan jumlah kode sedang atau lebih besar, refactoring bisa (luar biasa) sulit. Pengalaman saya bingung karena saya tidak memiliki dukungan perkakas untuk membantu dalam refactoring.

Saya akan membayangkan ada korelasi yang tinggi antara modul yang ditata sangat imperatif dan modul-modul yang idiomatik untuk ceruk pengembangan tertentu, yang kembali ke titik terakhir saya dibesarkan dengan outlier. Jadi modul apa pun yang Anda temukan untuk fungsionalitas itu akan terlihat seperti itu, dan Anda ingin para pakar dari domain itu dengan mudah dapat bekerja pada proyek Anda juga. Tetapi jika ada opsi dan tim Anda tidak suka gaya modul itu, maka saya akan menyelidiki opsi.

Demikian juga, saya telah bekerja dengan modul gaya OO yang berat di mana prinsip-prinsip OO diambil terlalu jauh dan digunakan secara tidak benar. Sebagai contoh, interface digunakan sebagai pengganti multiple inheritance. Dan seperti yang Anda duga, itu adalah implementasi yang kasar. Saya dapat membuat kemajuan yang wajar dalam refactoring modul itu, tetapi saya akhirnya meninggalkan pendekatan itu karena saya menemukan paket yang lebih baik untuk digunakan sebagai gantinya.


sumber
Itu cara yang bagus untuk menjelaskannya. Proyek serupa sekitar 300 KLOC.
Karl Bielefeldt
3

Sepertinya ada beberapa lapisan yang perlu dipertimbangkan, setidaknya:

  1. Perpustakaan yang ada dan modifikasi apa pun untuknya.
  2. Kode uji unit baru untuk pustaka tersebut.
  3. Lapisan abstraksi.
  4. API disajikan oleh lapisan abstraksi.
  5. Contoh dan kode uji menggunakan lapisan abstraksi.

Saya akan berasumsi bahwa tidak masuk akal untuk hanya refactor semua kode ke gaya umum di depan - jika itu Anda tidak akan mengajukan pertanyaan.

Mengambil masing-masing pada gilirannya:

  1. Untuk basis kode yang ada, maka Anda mungkin ingin tetap berpegang pada gaya itu.
  2. Kode uji unit baru untuk kode yang ada berdiri di area abu-abu, terutama tergantung pada seberapa banyak kode tersebut terintegrasi dengan kode lama. Tetapi kemungkinan besar, saya akan mencoba membuatnya dalam 'gaya yang disukai'.
  3. Kode baru di lapisan abstraksi. Dengan memastikan bahwa ini benar-benar lapisan kode yang terpisah, seharusnya tidak ada kesulitan dalam menggunakan gaya yang disukai meskipun kode melakukan banyak antarmuka dengan gaya atau gaya lama. Sebagian besar kode perlu berinteraksi dengan gaya lain, dan saya belum pernah menemukan masalah ini.
  4. Jelas API itu sendiri yang paling membutuhkan pemikiran dan memenuhi kebutuhan kegunaan maksimum.
  5. Contoh atau kode uji apa pun juga harus dapat ditulis dengan gaya yang disukai. Bergantung pada kelengkapan abstraksi (yaitu apakah benar-benar menyembunyikan lapisan bawah), ini mungkin mudah atau sulit. Tentu saja, memastikan bahwa kode klien masa depan dapat dibaca akan menjadi salah satu tujuan utama Anda.

Beberapa hal yang saya temukan secara pribadi adalah bahwa dengan basis kode legacy yang besar:

  • Menetapkan gaya yang disukai dan menerapkan perubahan kode itu secara ajaib tidak menghasilkan semua kode lama bermigrasi ke gaya baru.

  • Sebagian besar insinyur cenderung suka kode (lebih atau kurang) gaya yang ada di perpustakaan yang diberikan. Membutuhkan sebaliknya menghasilkan banyak penegakan.

  • Membutuhkan gaya yang disukai di perpustakaan lama cenderung menghasilkan banyak ketidakkonsistenan dalam gaya di perpustakaan itu. Jadi untuk standar yang murni seputar presentasi, tidak seperti ketahanan kode, sulit juga melihat banyak manfaat dalam mensyaratkannya.

Sebagai masalah terakhir (sedikit di luar topik tapi saya pikir relevan), kebenarannya adalah bahwa beberapa insinyur berjuang untuk tetap berpegang pada standar gaya apa pun selain mereka yang paling mereka kenal. Saya sangat merekomendasikan melibatkan tim dalam keputusan gaya dan memastikan ada pembelian. Setelah melakukannya, Anda berada dalam posisi yang jauh lebih baik untuk benar-benar menerapkan standar dalam kode campuran.

Keith
sumber
0

Saya akan setuju dengan @MetaFight di sini jika Anda sedang mengembangkan proyek berukuran besar dengan banyak modul pihak ketiga.

Mari kita memetakan masalah Anda dengan masalah kata nyata: " Misalkan Anda memiliki gaya hidup yang tenang di rumah Anda. Anda suka tempat Anda menjadi tenang, Anda tidak pernah berbicara lebih keras dan tidak pernah seperti anggota keluarga Anda untuk melakukannya. Tetapi Anda berinteraksi dengan banyak orang-orang yang berbeda di luar setiap hari untuk membawa sesuatu untuk rumah Anda. Tidak harus mereka juga akan berbicara dengan suara rendah, dalam hal ini Anda membentuk sendiri sesuai saat berurusan dengan orang-orang seperti itu. Dengan demikian antarmuka atau pembungkus untuk orang-orang ini sangat fleksibel hanya demi pekerjaanmu harus diselesaikan. "Contoh bodoh ... lol

Tapi maksud saya adalah untuk membuat wrapper untuk perpustakaan seperti sesuai standar pengkodean mereka sedemikian rupa sehingga Anda menggunakan perpustakaan ini melalui pembungkus ini mempertahankan gaya pengkodean asli Anda di dalam.

+1 untuk MetaFight.

theinsaneone
sumber
Solusi imo yang tepat. Saya menggunakan pembungkus untuk mengikat kode yang orang lain tulis untuk proyek saya juga. Tentukan antarmuka di depan, dan kemudian ketika mereka mengimplementasikannya, Anda dapat membungkusnya dan mengujinya di kotak hitam.
Kieveli
1
Mengapa ini diturunkan? Saya jelas berpikir itu adalah solusi terbaik :)
MetaFight
0

Ini jelas akan menyebabkan jumlah kebingungan paling sedikit untuk menggunakan gaya pengkodean tunggal di seluruh proyek Anda. Inti dari menggunakan gaya pengkodean di tempat pertama adalah membuat kode lebih mudah dibaca dan dimodifikasi.

Adapun gaya kode yang digunakan secara internal di perpustakaan, saya pikir itu tidak relevan. Jika pustaka terlalu penting, maka menulis pembungkus OO tidak masalah, tetapi itu tidak mengharuskan Anda menggunakan gaya kode yang sama seperti dalam contoh atau internal pustaka.

Gustav Bertram
sumber