Saya sangat ingin tahu tentang pemikiran dan praktik terbaik industri mengenai anggota statis, atau seluruh kelas statis. Apakah ada kerugian untuk ini, atau apakah ia berpartisipasi dalam anti-pola?
Saya melihat entitas ini sebagai "kelas utilitas / anggota", dalam arti bahwa mereka tidak memerlukan atau meminta instantiating kelas untuk menyediakan fungsionalitas.
Apa pemikiran umum dan praktik terbaik industri dalam hal ini?
Lihat contoh di bawah ini kelas dan anggota untuk menggambarkan apa yang saya rujuk.
// non-static class with static members
//
public class Class1
{
// ... other non-static members ...
public static string GetSomeString()
{
// do something
}
}
// static class
//
public static class Class2
{
// ... other static members ...
public static string GetSomeString()
{
// do something
}
}
Terima kasih sebelumnya!
c#
class-design
Thomas Stringer
sumber
sumber
Jawaban:
Secara umum, hindari statika - terutama segala keadaan statis.
Mengapa?
Statika menyebabkan masalah dengan konkurensi. Karena hanya ada satu contoh, itu secara alami dibagi di antara eksekusi bersamaan. Sumber daya yang dibagikan itu adalah kutukan dari pemrograman bersamaan, dan seringkali tidak perlu dibagikan.
Statika menyebabkan masalah dengan pengujian unit. Kerangka pengujian unit apa pun yang layak adalah pengujian menjalankan garam secara bersamaan. Kemudian Anda mengalami # 1. Lebih buruk lagi, Anda mempersulit pengujian Anda dengan semua hal pengaturan / teardown, dan peretasan yang Anda akan jatuh ke dalam mencoba dan "berbagi" kode pengaturan.
Ada banyak hal kecil juga. Statika cenderung tidak fleksibel. Anda tidak dapat antarmuka mereka, Anda tidak dapat menimpa mereka, Anda tidak dapat mengontrol waktu konstruksi mereka, Anda tidak dapat menggunakannya dengan baik dalam obat generik. Anda tidak dapat benar-benar versi mereka.
Tentu saja ada penggunaan statika: nilai konstan bekerja dengan baik. Metode murni yang tidak muat dalam satu kelas dapat bekerja sangat baik di sini.
Namun secara umum, hindari mereka.
sumber
volatile
. Anda tidak mendapatkan jaminan dari model memori tanpa data yang mudah menguap, jadi mengubah variabel dalam satu utas mungkin tidak langsung mencerminkan atau sama sekali.Jika fungsinya "murni" saya tidak melihat masalah. Fungsi murni hanya beroperasi di parameter input, dan memberikan hasil berdasarkan itu. Itu tidak tergantung pada negara global atau konteks eksternal.
Jika saya melihat contoh kode Anda sendiri:
Fungsi ini tidak mengambil parameter apa pun. Jadi, itu mungkin tidak murni (satu-satunya implementasi murni dari fungsi ini adalah mengembalikan konstanta). Saya berasumsi bahwa contoh ini tidak mewakili masalah Anda yang sebenarnya, saya hanya menunjukkan bahwa ini mungkin bukan fungsi murni.
Mari kita ambil contoh berbeda:
Tidak ada yang salah dengan fungsi ini statis. Kami bahkan bisa menjadikan ini sebagai fungsi ekstensi, yang memungkinkan kode klien menjadi lebih mudah dibaca. Fungsi ekstensi yang pada dasarnya hanya jenis khusus dari fungsi statis.
Telastyn dengan benar menyebutkan concurrency sebagai potensi masalah dengan anggota statis. Namun, karena fungsi ini tidak menggunakan status bersama, tidak ada masalah konkurensi di sini. Seribu utas dapat memanggil fungsi ini secara bersamaan tanpa ada masalah konkurensi.
Dalam kerangka NET., Metode ekstensi telah ada selama beberapa waktu. LINQ berisi banyak fungsi ekstensi (mis. Enumerable.Where () , Enumerable.First () , Enumerable.Single () , dll.). Kami tidak melihat ini sebagai buruk, kan?
Pengujian unit sering mendapat manfaat ketika kode menggunakan abstraksi yang dapat diganti, memungkinkan pengujian unit untuk mengganti kode sistem dengan uji ganda. Fungsi statis melarang fleksibilitas ini, tetapi ini terutama penting pada batas-batas lapisan arsitektur, di mana kami ingin mengganti, misalnya, lapisan akses data aktual dengan lapisan akses data palsu .
Namun, ketika menulis tes untuk objek yang berperilaku berbeda, tergantung pada apakah beberapa angka ganjil atau genap, kita tidak benar-benar perlu untuk dapat mengganti
IsOdd()
fungsi dengan implementasi alternatif. Demikian juga, saya tidak melihat kapan kita perlu memberikanEnumerable.Where()
implementasi yang berbeda untuk tujuan pengujian.Jadi mari kita periksa keterbacaan kode klien untuk fungsi ini:
Opsi a (dengan fungsi yang dinyatakan sebagai metode ekstensi):
Opsi b:
Fungsi statis (ekstensi) membuat potongan kode pertama jauh lebih mudah dibaca, dan keterbacaan sangat penting, jadi gunakan fungsi statis yang sesuai.
sumber