Pengulangan kode vs metode yang bertanggung jawab

11

Saya mencoba mengikuti Prinsip Tanggung Jawab Tunggal (SRP) dan juga menghilangkan Pengulangan Kode. Namun sering ada tempat di mana ada pengulangan kode yang tidak lebih dari blok kode doa yang tahan untuk mengekstraksi mereka ke dalam setidaknya metode yang bermakna:

DoAction1();
DoAction2();

if (value)
    DoAction3();

DoAction4();

Apa cara terbaik untuk mengekstrak kode seperti itu ke dalam metode dan bagaimana menamainya?

yee
sumber
1
Mengapa mereka tahan untuk diekstraksi menjadi metode yang bermakna berbeda?
Chandranshu
Semua tindakan melakukan sesuatu yang tidak terkait. Saya harus menulis: void MethodThatDoAction1ThenAction2AndAction3IfValueAndThenAction4(). Saya lebih suka melihat lebih banyak makna dalam: CodeBlock1().
yBee
4
Maka itu hanya masalah penamaan metode ekstraksi yang benar, kan? Saya khawatir tidak ada solusi universal dan Anda harus melakukan ini berdasarkan kasus per kasus. Jika Anda mengulangi potongan kode yang sama persis ini di lebih dari 1 tempat, pasti ada makna tindakan Anda dan Anda perlu terlihat keras (mungkin berdiskusi) untuk menemukan makna itu dan memberinya nama.
Chandranshu
1
Jika ada penghiburan, pemenang Spring untuk nama kelas panjang adalah AbstractInterruptibleBatchPreparedStatementSetteryang hanya sedikit lebih kecil dari metode Anda.
Chandranshu
1
@ Chandranshu Saya yakin komentar Anda akan berfungsi dengan baik sebagai jawaban untuk pertanyaan ini.
Simon Forsberg

Jawaban:

13

Saya pikir itu hanya masalah penamaan yang benar metode yang diekstraksi. Saya khawatir tidak ada solusi universal dan Anda harus melakukan ini berdasarkan kasus per kasus. Jika Anda mengulangi potongan kode yang sama persis ini di lebih dari 1 tempat, pasti ada makna tindakan Anda dan Anda perlu terlihat keras (mungkin berdiskusi) untuk menemukan makna itu dan memberinya nama.

Jika ada penghiburan, pemenang Musim Semi untuk nama kelas panjang adalah AbstractInterruptibleBatchPreparedStatementSetter49 karakter.

Chandranshu
sumber
11

Sebenarnya Anda menderita tugas tersulit yang harus dilakukan oleh seorang programmer - Penamaan Hal . Maaf untuk jawaban yang angkuh tetapi saya tidak bisa menolak. Anda dapat menemukan bahwa banyak orang menderita ini , bahkan di internet Anda dapat menemukan esai jenis ini .

Sekarang jika kode berulang Anda bersama-sama menghasilkan satu pekerjaan dan metode-metode itu tidak digunakan oleh metode lain maka mereka hanyalah metode Helpers dan kemudian metode yang dihasilkan dapat dinamai doXXXatau makeXXX... Saya pikir Anda mengerti maksudnya.

Seperti yang dikatakan Chandranshu , "Jika Anda mengulangi makna [...] ini dan berikan nama." adalah intinya dan tepat.

masukkan deskripsi gambar di sini

Foto milik: Foto Halaman CodeChef Facebook

Anirban Nag 'tintinmj'
sumber
2

Saya pikir Anda mengambil prinsip Pengulangan Kode terlalu jauh. Pikirkan titik menghindari Pengulangan Kode. Intinya adalah untuk mengurangi jumlah kode yang harus diperiksa ketika ada perubahan dalam logika, dan untuk meningkatkan pemahaman dengan memfaktorkan keluar blok yang jelas-jelas dimaksudkan dengan tujuan yang sama.

Kelemahan dari anjak keluar untuk menghindari Pengulangan adalah bahwa jika salah satu blok bersama harus berubah, sekarang Anda membutuhkan warisan yang lebih kompleks atau beberapa peralihan antara implementasi standar dan non-standar.

Jadi hati-hati mempertimbangkan kemungkinan logika untuk bahkan satu dari blok-blok ini berubah tanpa yang lain terhadap manfaat pemahaman yang diperoleh dengan memperhitungkan kesamaan ini. Jika satu implementasi bisa terpisah dari yang lain Anda mungkin lebih baik hanya mengulangi kode.

Sambil mempertahankan kode yang diulang ini, karena menjadi lebih kompleks dan domain masalah Anda menjadi lebih jelas, Anda dapat menemukannya lebih sesuai dengan faktor yang berulang, yang sekarang lebih kompleks, tetapi juga bagian yang lebih jelas.

Saya biasanya mencoba mempertahankan kesamaan teks-editor untuk sementara waktu sampai saya dapat melihat apakah sesuatu yang terlihat berulang-ulang ternyata layak diperhitungkan. Aku hanya mengulangi pengulangan, tapi aku tetap mengawasi masa depan blok itu dengan menjaganya agar mudah dicocokkan secara tekstual nanti.

Banyak waktu, kesamaan, dan kemungkinan anjak piutang, mulai menghilang, sebagai aturan bisnis yang nyata, berubah-ubah, dan sangat tergantung, sering kali logika sewenang-wenang; seperti berurusan dengan keanehan beberapa implementasi basis data yang umum (ANSI_NULLS atau semacamnya terlintas dalam pikiran) ditambahkan; memaksa apa yang tampak seperti logika murni menjadi kekacauan yang terpelintir, berusaha memberikan logika keputusan yang masuk akal dan dapat dipertahankan ketika berhadapan dengan kekacauan keadaan industri.

Tampak bagi saya bahwa jika orang mencoba memfaktorkan apa yang Anda coba faktorkan, kami akan memiliki seluruh pustaka konstruksi yang tidak bernilai seperti Do1Then2If2False Do1IfTrueDo2.

Itu harus lebih kompleks dan lebih jelas bahwa blok tidak akan berubah untuk menjamin anjak keluar.

Ini perangkat lunak . Anda dapat kembali dan mengedit beberapa blok yang sama sekarang. Butuh 5 menit. Dan Anda dapat menghemat berjam-jam anjak terbuang, dan kemudian jam lebih banyak warisan terbuang dan beralih pengembangan, dengan hanya meninggalkannya, dan memastikan Anda memiliki keyboard anti-RSI yang bagus.

Andyz Smith
sumber
Saya suka bagian yang mengekstrak esensi dari pengulangan kode: untuk mengurangi jumlah kode yang harus diperiksa ketika ada perubahan dalam logika
yBee
1

Jika Anda benar-benar mengikuti Prinsip Tanggung Jawab Tunggal, maka blok kode ini harus memiliki tujuan tertentu, bukan? Kalau tidak, metode ini akan berada di kelas yang terpisah.

Jadi, apa tujuan dari blok kode ini? Tentukan itu dan Anda harus dapat membuat nama.

Jika Anda masih tidak dapat mengetahui nama untuk benda ini, maka mungkin metode ini tidak benar-benar milik bersama sama sekali. Yakni blok kelas / kode ini memiliki lebih dari satu tanggung jawab. Dalam hal itu, refactoring untuk membagi tugas dapat mengungkapkan nama pengungkapan tujuan yang lebih baik.

Allan
sumber
1

Saya pernah mengalami situasi yang mirip dengan Anda:

Ada kelas yang mendefinisikan fungsionalitas objek yang diwakilinya:

class Functionality
{
protected:
void functionA();
void functionB();
...
void functionZ();
}

Lalu ada kelas yang mendefinisikan alur kerja untuk operasi tingkat tinggi yang dilakukan objek:

class Workflows: private Functionality
{
    void WorkflowA()
    {
        functionA();

        if (m_bValue) {
            functionB();
        }

        functionC();
    }
    ...
    void WorkflowB();
}

Jika Anda berada dalam situasi yang sama, maka identifikasi apa yang mewakili kelas Anda (dalam hal ini fungsionalitas / alur kerja) dan kemudian beri nama metode yang sesuai.

Penafian: Nama-nama kelas yang digunakan dalam contoh ini sangat tidak akurat, tetapi nama metode memberikan petunjuk. Kebijaksanaan disarankan.

perbaikan dotbug
sumber