KERING kode yang tidak terkait, tetapi hampir identik

34

Saya memiliki beberapa kode yang hampir identik, tetapi menggunakan jenis yang sama sekali berbeda, tanpa pewarisan di antara mereka, pada variabel utama. Secara khusus, saya menulis analisa dengan Roslyn untuk C # dan VB.NET, dengan tipe berikut:

Microsoft.CodeAnalysis.CSharp.Syntax.AttributeSyntax Microsoft.CodeAnalysis.VisualBasic.Syntax.AttributeSyntax

Saya bertanya-tanya apakah, karena kode melakukan hal yang sama, saya harus menjaganya tetap KERING mungkin, memisahkan sesedikit mungkin menjadi metode yang terpisah (tetapi identik selain jenisnya), atau benar-benar memisahkannya karena kedua metode tersebut adalah tidak terkait dan perubahan di masa depan dapat memaksa satu versi untuk berubah, tetapi tidak yang lain (meskipun ini tidak mungkin)?

Sunting: Setahun kemudian, saya mengenai masalah yang sama ini, dan tim Roslyn membantu saya menyelesaikannya: Tulis kelas dasar yang menggunakan generik dan memiliki TAttributeSyntaxparameter yang melakukan sebagian besar pekerjaan. Kemudian, tulis kelas turunan dengan data minimal yang membutuhkan jenis tertentu.

Hosch250
sumber
Apakah akan berhasil membuat antarmuka AttributeSyntax Anda sendiri yang membungkus kelas yang ada tetapi memberi Anda warisan yang secara konseptual harus ada di sana?
Winston Ewert
7
Maaf jika ini jelas, tetapi obat generik ada sehingga Anda tidak perlu mengulang sendiri untuk kode yang identik tetapi untuk jenis. Jika bukan itu yang Anda maksud, harap abaikan.
Davislor
@Lorehead Biasanya saya akan melakukan itu, tetapi ini adalah metode tunggal yang dilewati jenis yang berisi node sebagai muatan dari metode internal saya tidak punya kendali atas.
Hosch250
@ WinstonEwert Saya akan melihat itu. Saya tidak yakin saya ingin melakukan itu untuk semua tipe C # / VB.NET.
Hosch250
1
Refactoring memaksakan banyak kompromi dan terkadang bahkan paradoks. Misalnya kopling longgar vs. KERING, atau fungsi pendek, tetapi banyak darinya, vs. fungsi yang lebih panjang, dan beberapa darinya. Pada akhirnya, ini adalah binatang yang sulit: Target Anda adalah keterbacaan dan pemeliharaan. Anda harus berpikir sebagai avatar yang melihat kode Anda untuk pertama kalinya. Dan terkadang Anda hanya mencoba untuk melihat apa yang lebih baik. Sayangnya, refactoring sempurna tidak dimungkinkan.
phresnel

Jawaban:

111

Anda tidak melakukan KERING karena seseorang menulisnya di buku di suatu tempat yang baik untuk dilakukan, Anda melakukannya KERING karena sebenarnya memiliki manfaat nyata.

Khususnya dari pertanyaan itu:

Jika Anda mengulangi diri Anda sendiri, Anda dapat membuat masalah pemeliharaan. Jika doStuff1-3 semua memiliki kode terstruktur yang sama dan Anda memperbaiki masalah dalam satu, Anda bisa dengan mudah lupa untuk memperbaiki masalah di tempat lain. Juga, jika Anda harus menambahkan case baru untuk ditangani, Anda dapat dengan mudah memberikan parameter yang berbeda ke dalam satu fungsi daripada menyalin-menempel di semua tempat.

Namun, KERING sering dibawa ke ekstrem oleh programmer yang pintar. Kadang-kadang untuk tidak mengulangi diri sendiri, Anda harus membuat abstraksi, jadi anggap rekan tim Anda tidak bisa mengikutinya. Kadang-kadang struktur dua hal ini hanya samar-samar serupa tetapi cukup berbeda. Jika doStuff1-4 cukup berbeda sehingga refactoring mereka untuk tidak mengulangi diri Anda menyebabkan Anda harus menulis kode yang tidak wajar atau menjalani backflip pengkodean yang pintar yang akan menyebabkan tim Anda memelototi Anda, maka boleh saja mengulangi sendiri. Saya telah membungkuk ke belakang untuk tidak mengulangi diri saya beberapa kali dengan cara yang tidak wajar dan menyesali produk akhirnya.

Jadi, pada dasarnya, jangan berpikir "oh man, kode ini sangat mirip, mungkin saya harus refactor untuk tidak mengulangi sendiri". Pikirkan "apakah refactoring untuk membuat basis kode ini menggunakan kembali elemen umum membuat kode lebih dapat dipertahankan atau kurang terpelihara ?" Lalu, pilih salah satu yang membuatnya lebih bisa dirawat.


Yang sedang berkata, mengingat SRP dan hanya mencoba untuk memiliki kelas kecil, fleksibel umumnya, mungkin masuk akal untuk menganalisis kode Anda karena alasan itu , memecah bit perilaku yang menggunakan tipe generik (Anda mengatakan bahwa mereka identik selain tipe) menjadi kelas kecil. Kemudian Anda akan mengetahui bahwa beberapa kelas ini benar- benar identik (tidak hanya sebagian besar identik), dan kemudian Anda dapat membangun toolkit jika Anda ingin menambahkan Microsoft.CodeAnalysis.CPlusPlus.Syntax.AttributeSyntax.

durron597
sumber
32
TL; DR - KERING adalah sarana untuk mencapai tujuan. Fokuslah pada akhirnya, bukan pada sarana. Jika saya bisa menaikkan Lego Man dua kali, saya akan melakukannya.
Satu catatan penting: jika Anda melakukan ulangi diri, selalu menyebutkan dalam komentar semua tempat-tempat lain yang harus dikunjungi ketika perubahan kode diulang. Tidak hanya mengurangi kemungkinan desync, itu juga berfungsi sebagai indikator seberapa banyak rasa sakit pemeliharaan pengulangan yang menyebabkan Anda.
Xion