Saya sering mengalami masalah ini. Sebagai contoh, saya saat ini menulis fungsi baca dan fungsi tulis, dan mereka berdua memeriksa apakah buf
adalah pointer NULL dan bahwa mode
variabel berada dalam batas-batas tertentu.
Ini duplikasi kode. Ini dapat diatasi dengan memindahkannya ke fungsinya sendiri. Tetapi haruskah saya melakukannya? Ini akan menjadi fungsi yang cukup anemia (tidak banyak melakukan), agak terlokalisasi (jadi bukan tujuan umum), dan tidak berdiri sendiri (tidak tahu apa yang Anda butuhkan kecuali Anda melihat di mana itu berada bekas). Pilihan lain adalah dengan menggunakan makro, tetapi saya ingin berbicara tentang fungsi dalam posting ini.
Jadi, haruskah Anda menggunakan fungsi untuk hal seperti ini? Apa pro dan kontra?
coding-style
EpsilonVector
sumber
sumber
Jawaban:
Ini adalah besar penggunaan fungsi.
Itu bagus. Fungsi seharusnya hanya melakukan satu hal.
Dalam bahasa OO, jadikan ini pribadi.
Jika menangani lebih dari satu kasus, itu adalah tujuan umum. Selain itu, generalisasi bukan satu-satunya penggunaan fungsi. Mereka memang ada di sana untuk (1) menghemat Anda menulis kode yang sama lebih dari sekali, tetapi juga (2) memecah kode menjadi potongan-potongan kecil untuk membuatnya lebih mudah dibaca. Dalam hal ini mencapai (1) dan (2). Namun, bahkan jika fungsi Anda dipanggil dari satu tempat, itu mungkin masih membantu (2).
Datang dengan nama yang bagus untuk itu, dan itu berdiri sendiri. "ValidateFileParameters" atau sesuatu. Sekarang berdiri sendiri.
sumber
Itu benar-benar harus menjadi fungsi.
Jauh lebih mudah dibaca, dan lebih bisa dipelihara (jika logika cek berubah, Anda hanya mengubahnya di satu tempat).
Selain itu, hal-hal seperti ini dapat diuraikan dengan mudah sehingga Anda bahkan tidak perlu khawatir tentang overhead panggilan fungsi.
Izinkan saya mengajukan pertanyaan yang lebih baik. Bagaimana tidak melakukan ini praktik yang baik?
Lakukan hal yang benar. :)
sumber
return buffer != null;
maka saya pikir Anda menyakiti keterbacaan di sana.isBufferValid
jelas lebih mudah dibaca (dalam buku saya) daripadabuffer != null
, karena itu mengkomunikasikan tujuannya dengan lebih jelas. Dan lagi, belum lagi itu menyelamatkan Anda dari duplikasi juga di sini. Apa lagi yang kamu butuhkan?IMO, cuplikan kode layak dipindahkan ke fungsi mereka sendiri setiap kali ini membuat kode lebih mudah dibaca , terlepas dari apakah fungsinya akan sangat singkat atau hanya akan digunakan sekali.
Tentu saja ada batasan yang ditentukan oleh akal sehat. Anda tidak ingin memiliki
WriteToConsole(text)
metode dengan tubuh yang sederhanaConsole.WriteLine(text)
, misalnya. Tetapi berbuat salah di sisi keterbacaan adalah praktik yang baik.sumber
Ini umumnya ide yang baik untuk menggunakan fungsi untuk menghapus duplikasi dalam kode.
Namun itu bisa terlalu jauh. Ini adalah panggilan penghakiman.
Untuk mengambil contoh pemeriksaan buffer nol Anda, saya mungkin akan mengatakan bahwa kode berikut cukup jelas dan tidak boleh diekstraksi menjadi fungsi terpisah, bahkan jika pola yang sama digunakan di beberapa tempat.
Jika Anda memasukkan pesan kesalahan sebagai parameter ke fungsi pemeriksaan null generik, dan juga mempertimbangkan kode yang diperlukan untuk mendefinisikan fungsi, maka itu bukan penghematan LOC bersih untuk menggantikannya dengan:
Selain itu, harus menyelami fungsi untuk melihat apa yang dilakukannya ketika debugging berarti bahwa panggilan fungsi kurang "transparan" bagi pengguna, dan karenanya dapat dianggap kurang mudah dibaca / dikelola.
sumber
Memusatkan kode biasanya selalu merupakan ide yang bagus. Kita harus menggunakan kembali kode sebanyak mungkin.
Namun, penting untuk dicatat bagaimana melakukannya. Misalnya, ketika Anda memiliki kode yang melakukan compute_prime_number () atau check_if_packet_is_bad () itu bagus. Kemungkinannya adalah bahwa algoritma fungsi itu sendiri akan berkembang yang akan diuntungkan.
Namun, setiap bagian dari kode yang diulang sebagai prosa tidak memenuhi syarat untuk terpusat segera. Ini buruk. Anda dapat menyembunyikan baris kode sewenang-wenang di dalam suatu fungsi hanya untuk menyembunyikan kode, seiring waktu, ketika beberapa bagian aplikasi mulai digunakan, mereka semua harus tetap kompatibel dengan kebutuhan semua fungsi yang ada.
Inilah beberapa pertanyaan yang harus Anda tanyakan sebelum bertanya
Apakah fungsi yang Anda buat memiliki makna yang melekat sendiri atau hanya sekelompok garis?
Konteks lain mana yang akan membutuhkan penggunaan fungsi yang sama? Apakah Anda mungkin perlu sedikit menyamaratakan API sebelum menggunakan ini?
Apa yang akan menjadi harapan aplikasi (bagian yang berbeda dari) ketika Anda melemparkan pengecualian?
Apa skenario untuk melihat bahwa fungsi akan berkembang?
Anda juga harus memeriksa apakah sudah ada barang seperti ini. Saya telah melihat begitu banyak orang selalu cenderung mendefinisikan-ulang macro mereka MIN, MAX daripada mencari apa yang sudah ada.
Pada dasarnya, pertanyaannya adalah, "Apakah fungsi baru ini benar-benar layak untuk digunakan kembali atau ini hanya copy-paste ?" Jika itu yang pertama, itu baik untuk pergi.
sumber
Dupliaksi kode harus dihindari. Setiap kali Anda mengantisipasinya, Anda harus menghindari duplikasi kode. Jika Anda tidak mengantisipasinya, terapkan aturan 3: refactor sebelum potongan kode yang sama digandakan 3 kali, buat anotasi kekhasan saat digandakan 2 kali.
Apa itu duplikasi kode?
Pertimbangkan contoh di bawah ini:
menjadi
Anda meningkatkan enkapsulasi (sekarang Anda dapat mengubah kondisi menjadi admin secara transparan) dan semantik kode. Jika bug ditemukan dalam cara Anda memeriksa bahwa pengguna adalah admin, Anda tidak perlu membuang seluruh basis kode Anda dan membuat perbaikan di mana-mana (dengan risiko melupakannya dan mendapatkan kelemahan keamanan dalam aplikasi Anda).
sumber
KERING adalah tentang menyederhanakan manipulasi kode. Anda baru saja menyentuh titik baik tentang prinsip ini: Ini bukan tentang meminimalkan jumlah token dalam kode Anda, melainkan menciptakan satu titik modifikasi untuk kode yang setara secara semantik . Kedengarannya seperti cek Anda selalu memiliki semantik yang sama, sehingga harus dimasukkan ke dalam fungsi jika Anda perlu memodifikasinya.
sumber
Jika Anda melihatnya digandakan, Anda harus menemukan cara untuk memusatkannya.
Fungsinya adalah cara yang baik (mungkin bukan yang terbaik tetapi itu tergantung pada bahasanya) Bahkan jika fungsinya anemia seperti yang Anda katakan itu tidak berarti itu akan tetap seperti itu.
Bagaimana jika Anda harus memeriksa sesuatu yang lain juga?
Apakah Anda akan menemukan semua tempat Anda harus menambahkan cek tambahan atau hanya mengubah fungsi?
sumber
Hampir selalu baik jika kondisi berikut dipenuhi:
Dalam ruang lingkup yang lebih besar Anda harus mempertimbangkan duplikasi vs ketergantungan secara hati-hati. Contoh teknik pembatasan ruang lingkup: bersembunyi di bagian pribadi atau modul tanpa memaparkannya kepada publik.
sumber