Haruskah metode C # yang bisa statis menjadi statis?
Kami mendiskusikan ini hari ini dan saya agak ragu. Bayangkan Anda memiliki metode panjang yang memfaktor ulang beberapa baris. Metode baru mungkin mengambil beberapa variabel lokal dari metode induk dan mengembalikan nilai. Artinya, ini bisa jadi statis.
Pertanyaannya adalah: haruskah itu statis? Ini tidak statis berdasarkan desain atau pilihan, hanya berdasarkan sifatnya yang tidak mereferensikan nilai contoh apa pun.
Jawaban:
Tergantung. Sebenarnya ada 2 jenis metode statis:
Dalam basis kode ukuran kecil hingga sedang, Anda benar-benar dapat memperlakukan kedua metode tersebut secara bergantian.
Jika Anda memiliki metode yang termasuk dalam kategori pertama (can-be-static), dan Anda perlu mengubahnya untuk mengakses status kelas, relatif mudah untuk mencari tahu apakah mungkin mengubah metode statis menjadi metode instance.
Namun, dalam basis kode yang besar, banyaknya situs panggilan mungkin membuat penelusuran untuk melihat apakah mungkin untuk mengubah metode statis menjadi metode non-statis terlalu mahal. Banyak kali orang akan melihat jumlah panggilan, dan berkata "oke ... Lebih baik saya tidak mengubah metode ini, tetapi buat yang baru yang melakukan apa yang saya butuhkan".
Itu bisa mengakibatkan:
Kedua hal itu buruk.
Jadi, saran saya adalah jika Anda memiliki basis kode lebih dari 200K LOC, saya hanya akan membuat metode statis jika metode tersebut harus menjadi metode statis.
Pemfaktoran ulang dari non-statis ke statis relatif mudah (cukup tambahkan kata kunci), jadi jika Anda ingin membuat can-be-static menjadi statis aktual nanti (saat Anda membutuhkan fungsionalitasnya di luar instance) maka Anda bisa. Namun, pemfaktoran ulang terbalik, mengubah can-be-static menjadi metode instance JAUH lebih mahal.
Dengan basis kode yang besar, lebih baik membuat kesalahan di sisi kemudahan ekstensi, daripada di sisi kemurnian idealogis.
Jadi, untuk proyek besar jangan membuat hal-hal statis kecuali Anda membutuhkannya. Untuk proyek kecil, lakukan saja apa yang paling Anda sukai.
sumber
Saya tidak akan menjadikannya anggota statis publik dari kelas itu . Alasannya adalah membuatnya menjadi statis publik berarti mengatakan sesuatu tentang tipe kelas: tidak hanya "tipe ini tahu bagaimana melakukan perilaku ini", tetapi juga "adalah tanggung jawab tipe ini untuk melakukan perilaku ini." Dan kemungkinan besar perilaku tersebut tidak lagi memiliki hubungan nyata dengan tipe yang lebih besar.
Itu tidak berarti saya tidak akan membuatnya statis sama sekali. Tanyakan pada diri Anda ini: dapatkah metode baru secara logis dimiliki oleh tempat lain? Jika Anda bisa menjawab "ya" untuk itu, Anda mungkin ingin membuatnya statis (dan memindahkannya juga). Bahkan jika itu tidak benar, Anda masih bisa membuatnya statis. Jangan tandai itu
public
.Demi kenyamanan, Anda setidaknya bisa menandainya
internal
. Ini biasanya menghindari keharusan untuk memindahkan metode jika Anda tidak memiliki akses mudah ke jenis yang lebih sesuai, tetapi tetap membuatnya dapat diakses jika diperlukan dengan cara yang tidak akan muncul sebagai bagian dari antarmuka publik untuk pengguna kelas Anda .sumber
Belum tentu.
Memindahkan metode publik dari statis ke non-statis adalah perubahan yang mengganggu, dan akan membutuhkan perubahan untuk semua penelepon atau konsumen Anda. Jika suatu metode tampak seperti metode contoh, tetapi kebetulan tidak menggunakan anggota contoh apa pun, saya sarankan menjadikannya sebagai metode contoh sebagai ukuran pemeriksaan masa depan.
sumber
Iya. Alasan "itu bisa menjadi statis" adalah karena ia tidak beroperasi pada keadaan objek yang di atasnya ia dipanggil. Oleh karena itu, ini bukan metode instan, tetapi metode kelas. Jika itu dapat melakukan apa yang perlu dilakukan tanpa pernah mengakses data untuk contoh, maka itu harus statis.
sumber
Ya, seharusnya. Ada berbagai metrik penggandengan yang mengukur bagaimana kelas Anda bergantung pada hal-hal lain, seperti kelas lain, metode, dll. Membuat metode statis adalah cara untuk menjaga tingkat penggandengan tetap rendah, karena Anda dapat yakin bahwa metode statis tidak mereferensikan apa pun anggota.
sumber
Saya pikir itu akan membuatnya sedikit lebih mudah dibaca jika Anda menandainya sebagai statis ... Kemudian seseorang yang datang akan tahu bahwa itu tidak mereferensikan variabel instan apa pun tanpa harus membaca seluruh fungsi ...
sumber
Secara pribadi, saya penggemar berat keadaan tanpa kewarganegaraan. Apakah metode Anda memerlukan akses ke status kelas? Jika jawabannya tidak (dan mungkin tidak, jika tidak, Anda tidak akan mempertimbangkan menjadikannya metode statis), maka ya, lakukanlah.
Tidak ada akses ke negara lebih sedikit sakit kepala. Sama seperti ide yang baik untuk menyembunyikan anggota privat yang tidak dibutuhkan oleh kelas lain, merupakan ide yang baik untuk menyembunyikan status dari anggota yang tidak membutuhkannya. Akses yang berkurang dapat berarti lebih sedikit bug. Selain itu, ini membuat penguliran lebih mudah karena lebih mudah untuk menjaga anggota statis tetap aman. Ada juga pertimbangan performa karena runtime tidak perlu meneruskan referensi ini sebagai parameter untuk metode statis.
Tentu saja sisi negatifnya adalah jika Anda pernah menemukan bahwa metode statis Anda sebelumnya harus mengakses status karena alasan tertentu, maka Anda harus mengubahnya. Sekarang saya mengerti bahwa ini bisa menjadi masalah untuk API publik jadi jika ini adalah metode publik di kelas publik, mungkin Anda harus memikirkan implikasi dari ini sedikit. Tetap saja, saya belum pernah menghadapi situasi di dunia nyata di mana hal ini sebenarnya menyebabkan masalah, tapi mungkin saya hanya beruntung.
Jadi ya, lakukanlah, dengan segala cara.
sumber
Metode statis lebih cepat daripada metode non-statis jadi ya, metode tersebut harus statis jika bisa dan tidak ada alasan khusus untuk membiarkannya nonstatis .
sumber
Saya terkejut bahwa begitu sedikit yang menyebutkan enkapsulasi di sini sebenarnya. Metode instance akan secara otomatis memiliki akses ke semua bidang, properti, dan metode pribadi (instance). Selain semua yang dilindungi yang diwarisi dari kelas dasar.
Ketika Anda menulis kode, Anda harus menulisnya sehingga Anda mengekspos sesedikit mungkin dan juga agar Anda memiliki akses ke sesedikit mungkin.
Jadi ya, mungkin penting untuk membuat kode Anda cepat yang akan terjadi jika Anda membuat metode Anda statis, tetapi biasanya lebih penting dari itu adalah membuat kode Anda tidak mampu membuat bug juga. Salah satu cara untuk mencapainya adalah membuat kode Anda memiliki akses ke sesedikit mungkin "barang pribadi".
Ini mungkin tampak tidak relevan pada pandangan pertama karena OP jelas berbicara tentang refactoring yang tidak bisa salah dalam skenario ini dan membuat bug baru, namun kode refactored ini harus dipertahankan di masa depan dan dimodifikasi yang membuat kode Anda memiliki serangan yang lebih besar. surface "terkait bug baru jika memiliki akses ke anggota instance pribadi. Jadi secara umum saya pikir kesimpulan di sini adalah bahwa "ya, sebagian besar metode Anda harus statis" kecuali ada alasan lain untuk tidak membuatnya statis. Dan ini hanya karena "penggunaan enkapsulasi dan penyembunyian data yang lebih baik serta membuat kode 'lebih aman'" ...
sumber
Membuat sesuatu yang statis hanya karena Anda bisa bukanlah ide yang baik. Metode statis harus statis karena desainnya, bukan karena kebetulan.
Seperti yang dikatakan Michael, mengubah ini nanti akan merusak kode yang menggunakannya.
Dengan demikian, sepertinya Anda membuat fungsi utilitas privat untuk kelas yang sebenarnya statis menurut desain.
sumber
Jika Anda dapat melakukan refaktorisasi beberapa baris dan metode yang dihasilkan dapat menjadi statis, ini mungkin merupakan indikasi bahwa garis yang Anda tarik keluar dari metode tersebut sama sekali tidak termasuk dalam kelas penampung, dan Anda harus mempertimbangkan untuk memindahkannya ke kelas mereka sendiri.
sumber
Secara pribadi saya tidak punya pilihan selain membuatnya statis. Resharper mengeluarkan peringatan dalam kasus ini dan PM kami memiliki aturan "Tidak ada peringatan dari Resharper".
sumber
Itu tergantung tetapi umumnya saya tidak membuat metode tersebut statis. Kode selalu berubah dan mungkin suatu hari nanti saya ingin membuat fungsi itu virtual dan menggantinya dalam subclass. Atau mungkin suatu hari nanti perlu mereferensikan variabel instan. Akan lebih sulit untuk membuat perubahan tersebut jika setiap situs panggilan harus diubah.
sumber
Saya menyarankan bahwa cara terbaik untuk memikirkannya adalah ini: Jika Anda memerlukan metode kelas yang perlu dipanggil ketika tidak ada instance kelas yang instan, atau mempertahankan beberapa jenis status global, statis adalah ide yang bagus. Tapi secara umum, saya sarankan Anda lebih memilih membuat member non-static.
sumber
Anda harus memikirkan metode dan kelas Anda:
Jika dua yang terakhir adalah 'ya', maka metode / kelas Anda mungkin harus statis.
Contoh yang paling sering digunakan mungkin adalah
Math
kelasnya. Setiap bahasa OO utama memilikinya dan semua metodenya statis. Karena Anda harus dapat menggunakannya di mana saja, kapan saja, tanpa membuat contoh.Contoh bagus lainnya adalah
Reverse()
metode di C #.Ini adalah metode statis di
Array
kelas. Ini membalik urutan array Anda.Kode:
Ia bahkan tidak mengembalikan apapun, array Anda dibalik, karena semua array adalah instance dari kelas Array.
sumber
Selama Anda membuat metode baru menjadi privat statis, itu bukan perubahan yang mengganggu. Faktanya, FxCop menyertakan panduan ini sebagai salah satu aturannya ( http://msdn.microsoft.com/en-us/library/ms245046(VS.80).aspx ), dengan informasi berikut:
Meskipun demikian, komentar pertama dari David Kean secara lebih ringkas merangkum kekhawatiran dengan mengatakan ini sebenarnya lebih tentang menjadi benar daripada tentang perolehan kinerja:
sumber
Saya pasti akan mengubah apa pun yang saya bisa menjadi statis karena alasan yang berbeda:
Fungsi statis, ketika JIT, dipanggil tanpa parameter "ini". Itu berarti, misalnya, bahwa 3 parameter fungsi non-statis (metode anggota) didorong dengan 4 parameter pada tumpukan.
Fungsi yang sama yang dikompilasi sebagai fungsi statis akan dipanggil dengan 3 parameter. Ini dapat membebaskan register untuk JIT dan menghemat ruang tumpukan ...
sumber
Saya berada di kamp "hanya membuat metode pribadi statis". Membuat metode publik dapat memperkenalkan kopling yang tidak Anda inginkan dan dapat menurunkan kemampuan pengujian: Anda tidak dapat menghentikan metode statis publik.
Jika Anda ingin menguji unit metode yang menggunakan metode statis publik, Anda akhirnya menguji metode statis juga, yang mungkin bukan yang Anda inginkan.
sumber
Metode statis yang melekat yang karena alasan tertentu dibuat non-statis cukup mengganggu. Yakni:
Saya menelepon bank saya dan meminta saldo saya.
Mereka meminta nomor rekening saya.
Cukup adil. Metode instance.
Saya menelepon bank saya dan menanyakan alamat surat mereka.
Mereka meminta nomor rekening saya.
WTF? Gagal — seharusnya metode statis.
sumber
Saya melihatnya secara umum dari perspektif fungsional fungsi murni. Apakah itu perlu metode contoh? Jika tidak, Anda bisa mendapatkan keuntungan dari memaksa pengguna untuk memasukkan variabel dan tidak merusak status instance saat ini. (Yah, Anda masih bisa mengacaukan status, tetapi intinya adalah, secara desain, tidak melakukannya.) Saya biasanya merancang metode contoh sebagai anggota publik dan melakukan yang terbaik untuk membuat anggota pribadi statis. Jika perlu (Anda dapat mengekstraknya dengan lebih mudah ke kelas lain nanti.
sumber
Dalam kasus tersebut, saya cenderung memindahkan metode ke pustaka statis atau utils, jadi saya tidak akan mencampur konsep "objek" dengan konsep "kelas"
sumber