Apa argumen keluaran, sebagaimana dirujuk dalam Kode Bersih Martin?

14

Di halaman 45 dari Robert C. Martin Clean Code: A Handbook of Agile Software Craftsmanship, Martin menulis bahwa argumen keluaran harus dihindari. Saya mengalami kesulitan memahami arti "argumen keluaran" dan mengapa mereka harus dihindari.

Contoh Martin untuk argumen keluaran appendFooter(s);memanggil fungsi public void appendFooter(StringBuffer report). Peningkatan kodenya adalahreport.appendFooter();

Mungkin karena kurangnya konteks kode, tapi saya tidak melihat bagaimana menggunakan argumen keluaran dianggap pengkodean yang buruk. Bisakah seseorang menjelaskan konsep atau memberikan contoh kode tambahan untuk memahami hal ini?

Apakah fungsi berikut ini juga dapat dianggap sebagai contoh kode najis oleh prinsip di atas?

int[] numberArray = {3, 5, 7, 1};
sortArray(numberArray);

Jika hal di atas merupakan pelanggaran prinsip Martin karena tidak menggunakan argumen output, apakah lebih baik memiliki objek yang memiliki array sebagai bidang dan fungsi yang dapat dipanggil untuk mengurutkan array?

ObjectWithArrayField numberArray = new ObjectWithArrayField(3, 5, 7, 1);
numberArray.sort();
WP0987
sumber

Jawaban:

11

Bob Martin hanya berbicara tentang keterbacaan .

Masalah dengan appendFootercontohnya adalah, jika Anda menemukan baris kode appendFooter(s)di suatu tempat dalam suatu program, tidak segera jelas apakah panggilan itu mengambil ssebagai input dan menambahkannya di suatu tempat, atau jika shanya lulus untuk mengambil output dari fungsi itu. Yang pasti, Anda perlu memeriksa dokumentasi fungsi. Panggilan seperti report.appendFooter(), bagaimanapun, menghindari masalah itu: jauh lebih jelas sekarang apa yang terjadi.

Catatan, bagaimanapun, Bob Martin tidak mengatakan "tidak pernah menggunakan argumen keluaran", katanya "secara umum, Anda harus menghindarinya, karena itu akan membantu Anda untuk menjaga kode Anda sedikit lebih bersih". Jadi ini bukan aturan kultus braindead yang harus diikuti secara membabi buta.

Sortmetode untuk array dan koleksi standar sedikit berbeda. Memiliki sortmetode fungsi anggota dari setiap tipe data array standar akan memiliki beberapa kelemahan dari sudut pandang perancang bahasa, misalnya, memiliki metode seperti Array.sortmemungkinkan untuk menyimpan ini di perpustakaan standar, di luar runtime Java. Tetapi jika Anda ingin membuat tipe koleksi individual yang kadang-kadang harus disortir, menambahkan sortsebagai fungsi anggota mungkin memang ide yang lebih baik daripada menempatkannya ke dalam kelas yang terpisah.

Doc Brown
sumber
2
sortArray(numberArray), tentu saja, ada beberapa numberArraytempat. Atau apakah itu membuat salinan numberArray, mengurutkan salinan, dan mengembalikan salinan yang diurutkan tanpa mengubah numberArraysama sekali?
8bittree
@ 8bittree: itu benar, tapi itu bukan titik diskusi di sini - sort()metode wadah dapat bekerja di tempat juga, tanpa menggunakan "argumen keluaran". Jadi hanya karena sortArray(numberArray)metode in-place sama sekali tidak ada alasan yang membenarkan "bentuk argumen output".
Doc Brown
1
Maksud saya lebih dari itu tidak sepenuhnya jelas apa yang sortArray(numberArray)sedang dilakukan. Ini bisa menjadi jelas jika tidak mengembalikan jenis yang sama dengan yang diterimanya, maka itu harus ada di tempatnya. Tetapi tanpa melihat jenis kembali, atau jika jenis kembali cocok dengan jenis input, tidak jelas tanpa melihat definisi.
8bittree
1
@ 8bittree: Oke, Anda mengerti, saya menghapus pernyataan yang dipertaruhkan dari jawaban saya. Namun, masalah yang Anda uraikan tidak hilang dengan menggunakan fungsi anggota - bahkan fungsi anggota "semacam" bisa berperilaku seperti itu.
Doc Brown
11

Ini masalah menggunakan mekanisme yang tidak terduga untuk mengembalikan nilai dari fungsi, yang biasanya merupakan hasil dari melakukan terlalu banyak fungsi atau memiliki tanggung jawab yang tidak selaras. Sejauh ini, cara terbaik untuk mengkomunikasikan hasil fungsi adalah dengan menggunakan nilai balik. Saya harap itu jelas. Dalam bahasa berorientasi objek, metode terbaik kedua adalah bermutasi objek.

Di antara dua opsi itu, ada begitu banyak cara yang bersih dan jelas untuk mengomunikasikan hasil suatu fungsi sehingga jika Anda mendapati diri Anda ingin mengubah argumen sebagai satu-satunya cara, ada sesuatu yang salah dalam arsitektur Anda. Anda perlu mengatur ulang tanggung jawab kelas Anda sehingga orang yang melakukan mutasi memiliki data di tempat pertama.

Satu-satunya pengecualian adalah untuk algoritma yang sangat umum. Misalnya, algoritma pengurutan mungkin terpisah dari wadah yang diurutkannya, jika dapat diterapkan secara umum ke semua jenis wadah menggunakan antarmuka publik. Sebuah satu-shot appendFooterfungsi tidak memiliki alasan itu.

Karl Bielefeldt
sumber