Apakah ada kasus luar biasa di mana kami dapat menerima kode duplikat?

57

Saya sedang mengerjakan proyek perangkat lunak di mana kami harus membangun tiga API. Satu untuk saluran home banking, satu untuk saluran agensi dan yang ketiga untuk saluran seluler .

API agensi adalah yang paling lengkap karena memiliki semua fungsionalitas .. lalu API Beranda yang sedikit lebih kecil dan kemudian API seluler.

Arsitek di sini membuat layer umum (layanan lintas saluran EJB yang dibagikan oleh semua API). Tetapi kemudian API berbeda.

Tidak ada perbedaan besar untuk saat ini antara API. Tim besar mulai dengan saluran agensi, dan kami mengadaptasinya sekarang untuk saluran rumah. Kami hanya memperkaya objek khusus ke aplikasi rumah kami. Kalau tidak, kodenya 95% sama antara API. API dibangun di atas Spring MVC , dan memiliki (pengontrol, model & beberapa utilitas).

Pada dasarnya pengontrol melakukan pemetaan BO ke ChannelObject (menurut saya bukan tempat yang tepat untuk melakukan itu), dan beberapa utilitas tambahan dan serializers. Semua duplikat untuk saat ini. Mereka mengatakan bahwa alasan untuk duplikasi adalah mereka ingin API independen. "Jika besok kita menginginkan perilaku yang berbeda untuk rumah daripada agensi atau ponsel, kita tidak akan berjuang !!"

Apakah ada kasus di mana kita harus menerima kode duplikat?

Mohamed Amine Mrad
sumber
22
Dan jika tiga hari berikutnya, mereka memutuskan mereka ingin akses data yang konsisten dan representasi antara semua API ... yah ... "Perjuangan!"
Becuzz
26
Kode duplikat tidak selalu merupakan hal yang buruk. Ungkapan "KERING adalah musuh decoupling" tidak dapat cukup ditekankan. Setelah mengatakan itu, merancang untuk masa depan, daripada untuk sekarang, benar-benar adalah hal yang sangat buruk. Masa depan itu hampir tidak pernah terjadi. Alih-alih, rancang solusi yang sangat terpisah, dicakup oleh tes otomatis yang bagus untuk apa yang dibutuhkan sekarang. Kemudian, di masa depan, jika sesuatu yang berbeda diperlukan, akan lebih mudah untuk berubah.
David Arno
2
Saya pikir dua kasus di mana saya tidak pernah menyesali kode duplikat adalah (a) di mana kode duplikat adalah bagian yang sangat kecil dan tidak terlalu penting dari total, dan (b) di mana saya menyalin kode dari sistem yang sudah sekarat ke dalam sistem baru yang dirancang untuk umur panjang. Ada banyak kasus di mana saya menangis menangis setelah kode forking.
Michael Kay
14
Di mana saya telah bekerja, sering dicatat bahwa seseorang harus (sering) menggandakan satu kali, dan mengaburkan kesamaan untuk ketiga kalinya. Ini menghilangkan zeitgeist untuk abstraksi awal, yang mungkin tidak tepat, yang meningkatkan penggandaan alih-alih kohesi. Ketika persyaratan di masa depan benar-benar dipahami dengan baik, tentu saja pengecualian dapat dibuat.
Pieter Geerkens
3
Satu kasus sepele di mana kode duplikat dapat diterima adalah jika itu dihasilkan secara otomatis
samgak

Jawaban:

70

Duplikasi bisa menjadi hal yang benar untuk dilakukan, tetapi tidak untuk alasan ini.

Mengatakan "kita mungkin ingin tiga tempat dalam basis kode ini berperilaku berbeda meskipun saat ini, mereka identik" bukanlah alasan yang baik untuk duplikasi skala besar. Gagasan ini dapat berlaku untuk setiap sistem, dan dapat digunakan untuk membenarkan duplikasi apa pun , yang jelas tidak masuk akal.

Duplikasi harus ditoleransi hanya ketika menghapusnya akan secara keseluruhan lebih mahal sekarang karena beberapa alasan lain (tidak bisa memikirkan yang bagus saat ini, tetapi yakinlah akan ada satu - hampir semua yang ada dalam pemrograman merupakan trade-off daripada hukum).

Untuk apa yang Anda lakukan, solusi yang tepat bisa berupa mengekstraksi perilaku yang diduplikasi sekarang menjadi Strategi atau pola lain yang memodelkan perilaku sebagai kelas dan kemudian menggunakan tiga contoh dari kelas yang sama. Dengan begitu, ketika Anda melakukan ingin mengubah perilaku dalam salah satu dari tiga tempat, Anda hanya harus membuat strategi baru dan instantiate yang di satu tempat. Dengan begitu Anda hanya perlu menambahkan beberapa kelas dan membiarkan sisa basis kode hampir tidak tersentuh.

Kilian Foth
sumber
1
Jika dua hal berperilaku sama, itu duplikasi. Meskipun kecuali mereka berperilaku sama karena suatu alasan, mereka tidak boleh digabung. Bisakah satu mengekstrak beberapa bagian umum dari implementasi? Terkadang ada blok bangunan yang belum diabstraksi, siapa tahu.
Deduplicator
32
Sebagai contoh, kami memiliki sepotong kode yang digunakan oleh tiga bagian dari aplikasi kami, dan itu cukup banyak ditulis dengan banyak cabang bersyarat kecil di mana-mana untuk mencakup pengecualian untuk masing-masing dari ketiga. Tetapi , dan ini adalah bagian yang penting, ini telah banyak digunakan selama dua tahun tanpa laporan bug yang berarti. Jadi ketika bagian keempat dari aplikasi perlu melakukan sesuatu dengan itu, tetapi sekali lagi sedikit berbeda, keputusan dibuat untuk tidak menyentuh kode cacat yang berjalan dengan sempurna, dan hanya menyalinnya dan membuat basis fleksibel yang ditulis lebih baik, untuk masa depan.
KRyan
2
Duplikasi adalah hal yang tepat untuk dilakukan ketika biaya keterbacaan naik terlalu banyak jika dibandingkan dengan biaya pemeliharaan yang akhirnya disatukan. Saya tidak berpikir ini berlaku sama sekali dalam skenario ini, dan sering terlihat pada skala yang lebih kecil dalam suatu proyek, bukan sesuatu seperti ini. Bahkan saat itu sangat jarang Anda masuk ke situasi di mana hal ini terjadi, itu akan terjadi jika Anda memiliki duplikasi bersarang niche yang akan memaksa Anda untuk menggunakan pola Metode Templat atau sejenisnya tetapi di tempat-tempat kecil. Ini biasanya akan berakhir dengan kode yang membingungkan.
opa
Contoh di mana duplikasi berguna (dan "menghapusnya harus secara keseluruhan lebih mahal sekarang ") adalah pembatalan input dalam aplikasi web: Kami menggunakan validasi pertama (mungkin disederhanakan) pada klien sehingga pengguna mendapatkan umpan balik langsung tentang masalah; dan kemudian kami melakukan validasi yang sama (atau lebih menyeluruh) di server karena klien tidak dapat dipercaya.
Hagen von Eitzen
3
@HagenvonEitzen Tapi itu bahkan tidak perlu duplikasi, tergantung pada tumpukan teknologi. Misalnya, Anda mungkin memiliki input cek JavaScript di browser, dan kemudian Java memeriksa di server, sehingga Anda memiliki fungsi ganda. Tetapi jika Anda menjalankan Node.js di server, Anda bisa menggunakan validasi JavaScript yang sama di browser dan di server, menghilangkan duplikasi. Anda masih ingin kode dijalankan di banyak tempat (lingkungan tepercaya dan tidak tepercaya), tetapi kode tersebut tidak harus diduplikasi.
Joshua Taylor
87

Sandi Metz, seorang insinyur perangkat lunak dan penulis terkenal di ekosistem Ruby, memiliki posting blog yang hebat dan pembicaraan di mana dia juga berbicara tentang hubungan antara duplikasi dan abstraksi. Dia sampai pada kesimpulan berikut

duplikasi jauh lebih murah daripada abstraksi yang salah

Dan saya sepenuhnya setuju dengannya. Biarkan saya memberi Anda lebih banyak konteks untuk kutipan ini. Terkadang menemukan abstraksi yang tepat sangat sulit. Dalam kasus seperti itu, sangat menggoda untuk melakukan abstraksi untuk mengurangi duplikasi. Tetapi kemudian Anda mungkin menemukan bahwa abstraksi Anda tidak berlaku untuk semua kasus. Namun, itu mahal untuk mengubah segalanya lagi dan untuk pergi ke rute yang berbeda (untuk penjelasan yang jauh lebih baik tonton dia bicara!).

Jadi ya, bagi saya, ada kasus luar biasa, di mana menerima duplikasi adalah keputusan yang tepat, terutama ketika Anda tidak yakin apa yang akan terjadi dan persyaratan cenderung berubah. Dari posting Anda, saya menganggap ada banyak duplikasi sekarang, tetapi kolega Anda menyarankan bahwa ini mungkin berubah dan untuk tidak memasangkan kedua aplikasi satu sama lain. Menurut pendapat saya ini adalah argumen yang valid dan tidak dapat diabaikan secara umum.

larsbe
sumber
23
Ah ya, jika Anda tidak dapat menyimpulkan aturan yang digeneralisasikan, mencoba untuk mengabstraksikannya hanya bisa gagal. Dan jika korespondensi itu kebetulan, itu mungkin berumur pendek.
Deduplicator
5
Mungkin mahal untuk mengubah abstraksi begitu sudah ada, tetapi menghilangkan duplikasi begitu sudah ada bisa menjadi lebih banyak masalah. Tentu saja ini sangat tergantung pada bahasa dll. - Sistem tipe kuat-statis modern dapat melakukan pekerjaan dengan baik untuk membantu Anda mendapatkan bahkan perubahan skala besar untuk beberapa abstraksi dengan benar. Menjaga agar fitur yang digandakan tetap sinkron bukanlah sesuatu yang dapat banyak membantu sistem tipe Anda (karena duplikatnya, untuk tipe sistem , hanya berbeda). Tapi saya kira dalam bahasa dinamis, bahasa yang diketik bebek itu sebaliknya; jadi mungkin masuk akal untuk Ruby.
leftaroundabout
34

Jika orang mulai beralasan tentang desain dengan kata-kata "jika besok" , ini sering merupakan tanda peringatan besar bagi saya, terutama ketika argumen digunakan untuk membenarkan keputusan yang mencakup kerja dan usaha ekstra, yang tidak seorang pun benar-benar tahu apakah ini akan pernah membayar, dan mana yang lebih sulit untuk diubah atau dikembalikan daripada keputusan yang berlawanan.

Duplikasi kode mengurangi upaya hanya untuk jangka pendek, tetapi akan meningkatkan upaya pemeliharaan segera, sebanding dengan jumlah baris kode yang digandakan. Perhatikan juga bahwa setelah kode digandakan, akan menjadi sulit untuk menghapus duplikasi ketika ternyata ini adalah keputusan yang salah, sementara jika seseorang tidak menduplikasi kode sekarang, masih mudah untuk memperkenalkan duplikasi nanti jika ternyata tetap menempel pada KERING adalah keputusan yang salah.

Mengatakan bahwa, dalam organisasi yang lebih besar, kadang-kadang bermanfaat untuk mendukung independensi tim yang berbeda atas prinsip KERING. Jika menghapus duplikasi dengan mengekstraksi 95% bagian umum dari API dua komponen baru mengarah ke penggandengan dua tim independen, ini mungkin bukan keputusan paling bijaksana. Di sisi lain, jika Anda memiliki sumber daya terbatas dan hanya akan ada satu tim yang menjaga kedua API, saya yakin itu akan menjadi kepentingan mereka sendiri untuk tidak membuat upaya ganda dan menghindari duplikasi kode yang tidak perlu.

Perhatikan lebih lanjut itu membuat perbedaan jika "Rumah" dan "Agensi" API digunakan oleh aplikasi yang sepenuhnya berbeda secara eksklusif, atau jika seseorang mungkin mencoba untuk menulis membangun komponen di atas API yang dapat digunakan dalam konteks "Rumah" juga seperti dalam konteks "Agensi". Untuk situasi ini, memiliki bagian-bagian umum dari API persis sama (yang Anda hanya bisa menjamin jika bagian-bagian umum tidak digandakan), akan membuat pengembangan komponen seperti itu mungkin jauh lebih mudah.

Jadi jika ternyata akan ada sub tim yang benar-benar berbeda, masing-masing bertanggung jawab untuk masing-masing API, masing-masing dengan jadwal dan sumber daya yang berbeda, maka sekarang saatnya untuk menduplikasi kode, tetapi bukan "berjaga-jaga".

Doc Brown
sumber
3
Tanda peringatan yang lebih besar daripada "jika besok" bagi saya adalah "Itu tidak akan pernah berubah".
abuzittin gillifirca
@abuzittingillifirca: dan apa hubungannya dengan pertanyaan atau jawaban saya?
Doc Brown
1
Saya menantang paragraf pertama Anda.
abuzittin gillifirca
2
@abuzittingillifirca: yah, baca lagi pertanyaannya: ini tentang beralasan dengan argumen "jika besok" untuk membenarkan keputusan untuk duplikasi yang sulit untuk dikembalikan , sehingga membuat perangkat lunak sebenarnya lebih sulit untuk diubah untuk kasus-kasus tertentu. Ini mungkin sedikit berlawanan dengan intuisi, tetapi cara terbaik untuk menjaga peranti lunak tetap dapat diubah untuk masa depan adalah tidak membuat asumsi (mungkin salah) tentang masa depan, tetapi untuk menjaga peranti lunak sekecil dan sekuat mungkin.
Doc Brown
13

Duplikasi untuk mencegah kopling . Katakanlah Anda memiliki dua sistem besar dan Anda memaksa mereka untuk menggunakan perpustakaan yang sama. Anda mungkin menggabungkan siklus rilis kedua sistem. Ini mungkin tidak terlalu buruk tetapi katakanlah bahwa satu sistem perlu memperkenalkan perubahan. Yang lain perlu menganalisis perubahan dan mungkin terpengaruh. Terkadang hal itu dapat merusak banyak hal. Bahkan jika kedua belah pihak mampu mengoordinasikan perubahan itu bisa banyak pertemuan, melalui manajer, pengujian, dependensi dan akhir dari tim otonom kecil.

Jadi, Anda membayar harga kode duplikat untuk mendapatkan otonomi dan kemandirian.

Borjab
sumber
Jadi ini adalah duplikasi antar-komponen untuk menghindari kopling. Tetapi Anda masih ingin menghindari duplikasi intra-komponen, bukan?
TemplateRex
Ya, Anda ingin meminimalkan kode duplikat karena akan membuat kode Anda lebih mudah dipahami dan dimodifikasi. Tetapi ingat bahwa ada jawaban yang bagus dengan pengecualian yang masuk akal. Abstraksi yang tepat untuk menghindari duplikasi mungkin sulit ditemukan.
Borjab