Praktik terbaik untuk berbagi potongan kecil kode di seluruh proyek

102

Saya selalu berusaha mengikuti prinsip KERING secara ketat di tempat kerja; setiap kali saya mengulangi kode karena kemalasan, kode itu menggigit kembali nanti ketika saya harus mempertahankan kode itu di dua tempat.

Tetapi sering saya menulis metode kecil (mungkin 10 - 15 baris kode) yang perlu digunakan kembali di dua proyek yang tidak dapat saling referensi. Metode ini mungkin ada hubungannya dengan jaringan / string / MVVM dll. Dan merupakan metode yang umumnya berguna tidak spesifik untuk proyek tempat awalnya.

Cara standar untuk menggunakan kembali kode ini adalah membuat proyek independen untuk kode yang dapat digunakan kembali dan referensi proyek itu ketika Anda membutuhkannya. Masalahnya adalah kita berakhir di salah satu dari dua skenario yang kurang ideal:

  1. Kami berakhir dengan puluhan / ratusan proyek kecil - masing-masing untuk menampung kelas kecil / metode yang kami butuhkan untuk digunakan kembali. Apakah layak membuat yang baru .DLLhanya untuk sedikit kode?
  2. Kami berakhir dengan satu proyek memegang koleksi metode dan kelas yang tidak terkait. Pendekatan ini adalah apa yang dulu pernah saya lakukan di perusahaan tempat saya bekerja; mereka memiliki proyek bernama base.commonyang memiliki folder untuk hal-hal seperti yang saya sebutkan di atas: jaringan, manipulasi string, MVVM dll. Itu sangat berguna, tetapi merujuknya tanpa perlu diseret dengan itu semua kode yang tidak relevan yang tidak Anda butuhkan.

Jadi pertanyaan saya adalah:

Bagaimana sebaiknya tim perangkat lunak menggunakan kembali sedikit kode di antara proyek?

Saya tertarik terutama jika ada orang yang bekerja di perusahaan yang memiliki kebijakan di bidang ini, atau yang telah menemukan dilema ini secara pribadi seperti saya.


Catatan: Penggunaan kata "Proyek", "Solusi" dan "Referensi" berasal dari latar belakang dalam pengembangan .NET di Visual Studio. Tapi saya yakin masalah ini adalah bahasa dan platform independen.

George Powell
sumber
21
+1, meskipun saya pikir ada unsur humor dalam seseorang yang bekerja dengan .NET khawatir tentang menyeret kode yang tidak relevan melalui referensi DLL.
JDB
2
@ ColeJohnson. NET itu sendiri adalah referensi besar! Mungkin jauh lebih besar dari dll yang saya buat sendiri.
George Powell
2
Saya mengerti. Namun, kompiler JIT NET. Hanya memuat metode yang diperlukan ke dalam RAM (ketika mereka dipanggil)
Cole Johnson
1
Benar. Meskipun Anda masih harus mendistribusikan keseluruhan kerangka NET. Untuk siapa saja yang ingin menggunakan produk Anda, dan proyek-proyek besar dan solusi kompleks lebih sulit untuk dikelola.
George Powell

Jawaban:

75

Jika itu benar-benar metode / kelas yang dapat digunakan kembali, Anda dapat menuliskannya di sejumlah kecil perpustakaan 'Pisau Tentara Swiss'. Kami sering melakukan ini di perusahaan saya; kami menyebutnya framework framework:

  • Framework.Data - Utilitas untuk bekerja dengan permintaan basis data.
  • Framework.ESB - Metode standar untuk berinteraksi dengan bus layanan perusahaan kami
  • Framework.Logging - Sistem pencatatan terpadu
  • Framework.Services - Utilitas untuk berinteraksi dengan layanan web
  • Framework.Strings - Utilitas untuk manipulasi string lanjutan / pencarian string fuzzy dll.
  • ...

Secara keseluruhan, ada sekitar selusin perpustakaan. Anda benar-benar dapat mendistribusikan kode sesuai keinginan Anda, sehingga Anda tidak harus berakhir dengan ratusan atau membuang semuanya ke dalam satu unit raksasa. Saya menemukan pendekatan ini cocok karena hanya beberapa proyek kami akan perlu Framework.Datadan hanya sedikit yang akan membutuhkan Framework.Strings, sehingga konsumen dapat memilih hanya bagian-bagian dari kerangka kerja yang relevan dengan proyek khusus mereka.

Jika itu benar-benar hanya potongan, dan bukan metode / kelas aktual yang dapat dengan mudah digunakan kembali, Anda bisa mencoba mendistribusikannya sebagai potongan kode ke dalam IDE (mis. Potongan Kode Visual Studio ). Tim yang pernah bekerja sama dengan saya memiliki pustaka potongan umum yang memudahkan semua orang untuk mengikuti praktik pengkodean standar kami dengan kode internal juga.

pswg
sumber
4
+1 Ini akan menjadi pendekatan saya juga. Tertarik untuk mengetahui bagaimana Anda memutuskan di mana harus meletakkan kode yang berhubungan dengan barang dari dua aspek atau lebih. Misalnya IPAddressToString. Dan apakah Anda mengizinkan perpustakaan ini untuk saling menggunakan. Misalnya layanan dan data mungkin bisa mendapat banyak manfaat dari pencatatan ...
Marjan Venema
5
@MarjanVenema Untuk kode lintas sektoral, itu tergantung pada konsumen mana yang akan menemukan metode yang lebih berguna. Sebab IPAddressToString, kemungkinan konsumen yang berurusan dengan protokol jaringan harus menggunakannya, tetapi konsumen yang banyak mengotak-atik string mungkin tidak terlalu peduli dengan alamat IP sama sekali. Itu mungkin akan berakhir dalam paket jaringan daripada Framework.Strings.
pswg
@MarjanVenema Kami mencoba menghindari saling ketergantungan. Layanan dan kerangka kerja data kami ditulis sedemikian rupa sehingga mereka tidak melakukan logging sendiri, tetapi memudahkan konsumen untuk menulis kode logging yang tepat. Kerangka pustaka diizinkan untuk saling referensi, tetapi hanya dengan ekstensi - misalnya Framework.Logging.Gibraltaradalah tambahan khusus untuk sistem logging.
pswg
5
+1 Anda bisa mengambil pustaka kerangka kerja ini dan menyebarkannya ke repositori NuGet internal (semudah folder jaringan) dan Anda punya cara yang bagus untuk mengelolanya.
Steven Evers
2
@SteveEvers Saya sebenarnya sedang bekerja sekarang untuk mengaturnya. : P
pswg
21

Saya tidak setuju dengan jawaban yang diterima karena berbagai alasan.

Dalam pengalaman saya, ketika saya melihat perpustakaan "lain-lain" seperti jawaban yang diterima, mereka adalah alasan untuk menemukan kembali roda (atau tidak ditemukan di sini (NIH) ) - dosa yang jauh lebih besar daripada melanggar Dont Repeat Yourself (DRY) .

Kadang-kadang melanggar KERING bisa menjadi kompromi yang masuk akal, itu lebih baik daripada memperkenalkan kopling ketat. Penggunaan kembali adalah masalah sekunder dibandingkan dengan desain berorientasi objek yang baik. Sedikit (maksud saya jumlah kecil, menerapkan Aturan Tiga ) dari duplikasi lebih mudah dipahami daripada basis kode spaghetti.

Pendekatan berbagai perpustakaan tujuan umum memberikan contoh yang buruk. Ini mengarah ke granularity halus perakitan dan terlalu banyak majelis buruk. Baru-baru ini saya mengurangi in-house dari 24 perpustakaan menjadi 6 perpustakaan. Ini meningkatkan waktu kompilasi dari beberapa menit menjadi ~ 20 detik. Visual studio juga lebih lambat untuk memuat dan kurang responsif dengan lebih banyak perangkat. Memiliki terlalu banyak perpustakaan juga menyebabkan kebingungan tentang di mana kode harus hidup; lebih suka aturan yang lebih sedikit dan lebih sederhana.

Mengapa hal-hal di .Net Framework tidak cukup baik? Kerangka ini cukup besar; berkali-kali saya melihat kode yang mengimplementasikan kembali hal-hal yang sudah ada di sana. Benar-benar memastikan bahwa kerangka kerja Anda mengisi celah dalam kerangka .Net dan jangan hanya ada karena alasan estetika (misalnya "Saya tidak suka kerangka .Net di sini" atau mungkin beberapa optimasi dini )

Memperkenalkan lapisan lain ke dalam arsitektur Anda memiliki biaya kompleksitas yang signifikan. Mengapa lapisan itu ada? Saya telah melihat penggunaan kembali yang salah, maksud saya, kode tersebut dibangun di atas kerangka kerja in-house. Akan jauh lebih efisien untuk mengimplementasikannya langsung di atas perpustakaan standar.

Menggunakan teknologi terstandarisasi (seperti .Net framework dan perpustakaan pihak ketiga / sumber terbuka populer) memiliki manfaat yang seringkali lebih besar daripada keuntungan teknologi komparatif dari membangunnya sendiri. Lebih mudah menemukan bakat yang mengetahui teknologi ini dan pengembang yang ada akan berinvestasi lebih banyak untuk mempelajarinya.

Rekomendasi saya:

  • Jangan bagikan kode ini.
  • Buat perpustakaan baru jika memiliki tujuan kohesif jangan gunakan bola pola desain lumpur .
  • Gunakan kembali perpustakaan pihak ke-3 yang ada jika memungkinkan.
  • Lebih suka majelis lebih sedikit, dengan aturan sederhana tentang tempat kode harus hidup.
Dave Hillier
sumber
1
Manfaat tambahan untuk menggunakan pustaka Open Source di mana tersedia - jika Anda menemukan beberapa perbaikan, Anda dapat membagikannya kembali ke komunitas! Misalnya dengan .Net MS menerbitkan EnterpriseLibrary (sekarang Open Source) yang memberikan seperangkat alat yang cukup bagus untuk skenario umum, temukan sesuatu di sana yang dapat ditingkatkan dan hei presto! Semua orang mendapat manfaat!
glenatron
2
Saya tidak benar-benar melihat ketidaksepakatan dengan jawaban yang diterima di sini :-). "lebih sedikit majelis, dengan aturan yang lebih sederhana tentang tempat kode harus hidup" bukan kontradiksi dengan jawaban yang diterima. Jawabannya juga menganjurkan hanya menggunakan banyak majelis berbeda yang tampaknya masuk akal.
sleske
Lima tahun kemudian bimbingan Microservice juga bertemu pada praktik ini: medium.com/standard-bank/…
Dave Hillier
11

Untuk bit kode yang kecil - misalnya satu kelas tanpa ketergantungan - kita cenderung hanya menyalin dan menempelkan kode ke proyek. Ini terdengar seperti pelanggaran KERING, dan saya akui kadang-kadang. Tetapi dalam jangka panjang itu jauh lebih baik daripada memiliki semacam proyek bersama multi-kepala besar karena beberapa alasan.

Pertama, itu hanya lebih mudah untuk memiliki kode berguna, terutama ketika membangun dan men-debug barang.

Kedua, selalu Anda ingin membuat sedikit perubahan pada kode umum untuk proyek itu. Jika Anda memiliki salinan lokal dari sumber tersebut, Anda hanya dapat melakukan tweak dan menyebutnya sehari. Jika ada pustaka bersama maka Anda bisa melakukan tweaking pustaka itu dan kemudian memastikan Anda tidak merusak semua aplikasi lain atau membuat mimpi buruk versi.

Jadi, jika tidak cukup besar untuk namespace itu sendiri, kita cenderung untuk mendorongnya ke bit yang sesuai pada proyek dan menyebutnya sehari.

Wyatt Barnett
sumber
5
Saya tidak setuju dengan pendekatan ini. Saya menghargai masalah pemeliharaan dengan mengelola potongan-potongan kode kecil tapi saya berpendapat bahwa beberapa perpustakaan umum dapat dibuat dari semuanya seperti @ psw menyarankan. Memiliki duplikat kode dengan tweak kecil di dalamnya meminta masalah. Asumsi akan dibuat, perbaikan bug akan dilewatkan.
Andrew T Finnell
2
-1 (untuk jawabannya). Tentunya lebih mudah bagi setiap orang untuk memiliki salinan program versi mereka sendiri. Inilah bagaimana perangkat lunak dikembangkan di tahun 80-an. Saya telah belajar bahwa - dalam jangka panjang - ini menyebabkan kekacauan. Lebih sulit untuk melakukan hal yang benar dan memiliki perpustakaan umum karena orang-orang harus berkomunikasi lebih banyak tentang pekerjaan mereka. Yah, mereka seharusnya.
Michael Durrant
3
+1 - Saya pikir perlu menyebutkan pendekatan ini meskipun itu bukan pendekatan yang sangat ingin Anda gunakan. Beberapa cuplikan lebih mirip pola desain - Anda akan menggunakannya kembali, tetapi sedikit berbeda di mana-mana, dan mungkin dalam bahasa yang berbeda, dan mungkin Anda ingin mengubahnya. Juga, pustaka yang digunakan kembali secara luas tidak fleksibel karena perubahan pada API-nya sangat berisiko. Akhirnya, memiliki pendekatan ini sebagai mundur meningkatkan kualitas perpustakaan bersama dengan menjaga hal-hal eksperimental dari mereka sedikit lebih lama.
Eamon Nerbonne
6

Solusi kedua yang Anda jelaskan tidak terlalu buruk. Di .NET Anda juga mereferensikan perakitan dari GAC bahkan jika Anda hanya menggunakan satu kelas saja. 'Menyeret kode yang tidak relevan' bukanlah masalah yang mungkin Anda pikirkan. Dalam hal ini sangat penting untuk setidaknya menjaga metode dan kelas yang terkait diatur secara rapi dalam ruang nama yang berbeda. Selain itu praktik yang baik untuk desain API harus diterapkan untuk mencegah solusi ini menjadi berantakan.

Jika menyangkut bit kode yang sangat kecil, saya pikir pendekatan berikut ini merupakan pelengkap yang baik untuk proyek umum: Izinkan mereka digandakan dalam solusi yang berbeda. Berurusan dengan mereka seperti praktik terbaik: dokumentasikan dan komunikasikan kepada tim.

Theo Lenndorff
sumber
1
Kecuali untuk pustaka non-standar, ini berarti Anda harus mengirimkan rakitan besar hanya karena satu (atau beberapa) penggunaan. Ini bukan masalah untuk barang-barang standar seperti yang tersedia, tapi saya pasti akan menghindari pengiriman rakitan besar tetapi kebanyakan tidak digunakan jika Anda dapat membaginya dengan cara yang baik.
colek
6

Saya hanya pernah bekerja di lingkungan "perusahaan" di mana hal semacam ini telah menjadi masalah dan setiap kali itu merupakan opsi kedua yang diadopsi. Sebagian besar itu berfungsi dengan baik karena belum ada kendala pada jejak aplikasi.

Namun, setelah menghabiskan minggu terakhir dengan start-up yang menjalankan server Nuget mereka sendiri, saya cenderung menyarankan ini sebagai alternatif yang layak. Tentu saja masalah yang saya harapkan akan muncul adalah kemampuan menemukan.

Jika proyek-proyek yang sesuai granular dan ruang nama masuk akal maka saya bisa melihat ini menjadi pendekatan yang populer di beberapa tempat.

Kofi Sarfo
sumber
Dalam hal apa Anda berharap mereka tidak dapat ditemukan? Kami menggunakan banyak paket nuget dengan cara itu. Masalah terbesar yang kita miliki adalah mengelola versi dan dependensi.
pdr
Ah iya. Itu juga. Dengan masalah seputar kemampuan menemukan yang saya maksudkan bahwa dengan cukup banyak paket kecil dengan fungsi spesifik mungkin akan lebih sulit untuk membuat katalog (dan menemukan) masing-masing. Misalnya, bagaimana tim Anda membuat paket mana yang berisi berbagai fungsi? (menunjukkan ketidaktahuan pencarian nuget di sini)
Kofi Sarfo
Oh begitu. Ya, Anda pasti bisa memasukkan apa pun yang Anda suka dalam deskripsi dan itu bisa dicari, tapi saya pikir kami sudah mengelompokkan paket dengan cukup baik sehingga tampaknya tidak menjadi masalah.
pdr
@sarfeast Akan lebih baik jika Anda dapat membagikan tautan ke server Nuget apa pun, dan memberi tahu sedikit tentangnya.
Hans-Peter Störr
6

Saya baru-baru ini memikirkan hal ini dan apa yang terjadi pada saya adalah perpustakaan besar metode umum seperti yang telah disebutkan sejauh ini, tetapi dengan twist. Proyek perpustakaan akan memungkinkan Anda untuk mengkonfigurasi pada waktu kompilasi bagian mana yang termasuk jenis seperti proyek BusyBox . Dengan pendekatan itu, Anda dapat memiliki repo perpustakaan gaya wastafel dapur, tetapi hanya mengambil alat yang Anda butuhkan saat kompilasi.

Harvey
sumber
5

GitHub memiliki alat yang sangat berguna untuk menyimpan cuplikan kode https://gist.github.com/

Ini menyimpan cuplikan Anda sebagai repositori git yang dapat Anda jaga kerahasiaannya, atau gunakan untuk berbagi cuplikan dengan orang lain.

blacksh33p
sumber
3

Bergantung pada ukuran tim / proyek / perusahaan, ini akan menjadi hal yang agak sulit untuk dilakukan secara efektif, kecuali itu sudah ada di dalam lingkungan Anda, dan setiap solusi yang Anda temukan (jika Anda implementasikan) akan memerlukan biaya. (Ini mungkin membuat Anda lebih aman, tetapi Anda tidak akan bisa mengukur dengan mudah). Anda harus memeriksa apakah harganya pantas. Perlu diingat juga, bahwa solusi yang dapat digunakan kembali cenderung menjadi abstrak dan seringkali cocok dengan banyak situasi tetapi tanpa menjadi optimal.

Bagaimanapun, jika Anda ingin melakukan ini untuk kode yang dihasilkan oleh lebih dari satu orang, pada awalnya Anda akan membutuhkan kesadaran semua orang dan kerja sama. Ini termasuk pengembang dan manajer.

Maka Anda harus memastikan Anda tahu ruang lingkup di mana Anda ingin melakukan ini. Tim? Proyek? Departemen? Perusahaan? Bergantung pada jawaban, jenis kode yang akan Anda masukkan ke dalam solusi semacam itu akan berbeda-beda, demikian juga rincian yang Anda gunakan untuk menyesuaikan dll. Setelah Anda memutuskan seseorang ini (lebih disukai dengan antusiasme untuk ide - Anda?) Harus duduk dan mulai meletakkan beberapa struktur ke dalam ini.

Hanya dengan membuat dll tidak akan cukup untuk melakukan trik. Untuk menjadikannya berguna, Anda harus mengiklankannya (kepada pengguna dan kontributor) dan mempertahankannya seperti perangkat lunak lainnya, yang biasanya berarti bahwa Anda harus membuat seseorang bertanggung jawab untuk mereka untuk waktu yang lama. Anda juga akan memerlukan dokumentasi yang dapat diandalkan, yang kemudian akan membutuhkan pemeliharaan juga. Dengan sedikit keberuntungan dan kerja sama Anda mungkin berakhir dengan beberapa praktik terbaik, tetapi juga dapat dengan mudah berkembang menjadi proyek sendiri, tergantung pada ukuran dan jumlah tim yang terlibat. Dan untuk itu Anda masih memerlukan dukungan manajemen.

Thomas
sumber
3

saya telah mengalami banyak masalah, dan solusi yang saya sukai adalah memposting kode dalam repositori github / pubic web-enabled. itu memecahkan banyak masalah -

  1. akses mudah dan mudah untuk dibagikan. cvs / svn / enterprise-repos berarti memeriksa proyek menjadi beberapa ruang kerja IDE, dan terkadang harus beralih ruang kerja atau komputer hanya untuk merujuk ke cuplikan kode kecil.
  2. dengan asumsi potongan kode ini bukan hak milik / bagian dari kode dan merupakan variasi dari pengetahuan yang tersedia untuk umum, mempostingnya di repo publik seperti github berarti orang lain akan melihatnya, dan bahkan mungkin berkontribusi.
  3. memposting sesuatu di domain publik dengan nama Anda memiliki tekanan tambahan untuk reputasi. Anda akan mengecek dan memperbarui hal-hal, karena itu mencerminkan kemampuan Anda sebagai seorang programmer.
  4. pembaruan. satu hal tentang menjaga potongan kode dalam repo adalah, jika snippet tidak digunakan dalam waktu yang lama, mungkin basi (mengandung apis / lib yang kedaluwarsa). contoh - cuplikan kode java untuk membaca file. Anda mungkin telah menemukan cara terbaik untuk melakukan ini pada tahun 2009, tetapi pada tahun 2014 muncul file baru yang mengubah segalanya. cuplikan Anda? masih macet pada tahun 2009. dalam repo publik, hal-hal akan diperbarui, baik oleh Anda (karena bullet 3), rekan tim Anda, atau beberapa anggota populasi programmer umum, dan dalam proses tersebut, Anda mungkin bahkan mendapatkan saran untuk memperbaiki sesuatu yang Anda mungkin telah melakukan kesalahan untuk waktu yang lama.

Satu hal yang saya sarankan - di mana pun Anda menyimpan snippet Anda, selalu perbaiki google sebelum menggunakannya. semuanya berubah sepanjang waktu. cuplikan yang disimpan menghemat waktu, tetapi juga menghasilkan rasa puas diri .

Quest Monger
sumber
2

Kami memiliki "utilitas" proyek terpisah di mana kami menyimpan semua metode kecil ini bersama dengan tes.

Ketika sebuah proyek membutuhkan utilitas, ia hanya menambahkan file sumber dengan metode yang diperlukan dengan "tambahkan sebagai tautan".

Ini berarti bahwa tidak ada dependensi run time yang ditambahkan (kecuali file yang disertakan memerlukannya).

Sistem telah bekerja dengan baik, tetapi seperti semua yang lain, sistem ini perlu dikuasai apa itu utilitas. Meminta cakupan tes tinggi telah bekerja dengan baik untuk kami dan tes juga merupakan dokumentasi penggunaan yang baik. Penemuan masih merupakan masalah yang belum terpecahkan bagi kami.

Satu kerumitan dengan proyek utilitas adalah memutuskan tingkat visibilitas pada item. Aturan praktisnya adalah bahwa metode harus internal dan struktur data publik.

adrianma
sumber
2

Perusahaan saya menggunakan layanan web intranet-lokal. Kami memiliki beberapa layanan web yang ditetapkan sebagai layanan web internal umum, dan ketika proyek lain membutuhkan akses ke salah satu layanan, ia mengirimkan permintaan http dengan antarmuka yang ditentukan. Karena ada di intranet, bertempat di server server yang sama, permintaan ini sangat cepat.

Jelas ini hanya bekerja dengan aplikasi internet (dan hanya bekerja dalam milidetik di jaringan lokal yang sama), tetapi ini memiliki beberapa keuntungan yang sangat bagus.

Ben Lee
sumber
0

Saya baru-baru ini datang dengan layanan ini: Snip2Code ( http://www.snip2code.com ).

Ini cara yang menarik untuk berbagi hanya cuplikan Anda (tidak sepenuhnya perpustakaan) dengan tim Anda. Itu mematahkan titik biasa untuk membuat perpustakaan umum yang harus dirujuk dalam proyek lain, dan menurut saya ini adalah visi yang berharga.

Selain itu, ada banyak skenario di mana penggunaan perpustakaan umum tidak berlaku: mari kita pertimbangkan misalnya beberapa Pola Desain seperti Singleton, Strategy atau Observer. Anda dapat membuat perpustakaan untuk mendukung pola seperti itu tetapi masih belum ada cakupan 100%.

Kebutuhan sebenarnya adalah memiliki alat untuk berbagi praktik umum di antara tim. Saya mencoba menggunakan intisari Github tetapi saya terjebak dengan pencarian mereka (benar-benar buruk) dan dengan fakta bahwa saya tidak dapat membagikannya hanya di antara tim saya dan tidak dengan yang lain ...

(Penafian: Saya salah satu pendiri Snip2Code, dan saya - bersama dengan rekan pendiri saya - dalam pola pikir Anda yang sama beberapa waktu yang lalu: inilah mengapa kami memutuskan untuk memulai proyek ini !!)

Cristiano Ghersi
sumber