Saya baru-baru ini meninjau beberapa kelas statis "utilitas tas" Helper mengambang di sekitar beberapa kode C # besar yang saya kerjakan, hal-hal yang pada dasarnya seperti cuplikan yang sangat ringkas:
// Helpers.cs
public static class Helpers
{
public static void DoSomething() {}
public static void DoSomethingElse() {}
}
Metode spesifik yang saya ulas adalah
- sebagian besar tidak terkait satu sama lain,
- tanpa negara eksplisit bertahan di doa,
- kecil, dan
- masing-masing dikonsumsi oleh berbagai jenis yang tidak terkait.
Sunting: Di atas tidak dimaksudkan untuk menjadi daftar masalah yang diduga. Ini adalah daftar karakteristik umum dari metode spesifik yang saya ulas. Konteksnya untuk membantu jawaban memberikan solusi yang lebih relevan.
Hanya untuk pertanyaan ini, saya akan merujuk pada metode semacam ini sebagai GLUM (metode utilitas umum ringan). Konotasi negatif "murung" sebagian dimaksudkan. Saya minta maaf jika ini dianggap sebagai permainan kata bodoh.
Bahkan mengesampingkan skeptisisme default saya sendiri tentang GLUM, saya tidak suka hal-hal berikut tentang ini:
- Kelas statis digunakan hanya sebagai namespace.
- Identifier kelas statis pada dasarnya tidak ada artinya.
- Ketika GLUM baru ditambahkan, baik (a) kelas "tas" ini disentuh tanpa alasan yang baik atau (b) kelas "tas" baru dibuat (yang dengan sendirinya biasanya tidak menjadi masalah; yang buruk adalah bahwa baru kelas statis sering hanya mengulangi masalah yang tidak terkait, tetapi dengan metode yang lebih sedikit).
- Meta-penamaan adalah tak terelakkan mengerikan, non-standar, dan biasanya secara internal tidak konsisten, apakah itu
Helpers
,Utilities
, atau apa pun.
Apa pola yang cukup bagus & sederhana untuk refactoring ini, sebaiknya mengatasi masalah di atas, dan lebih disukai dengan sentuhan seringan mungkin?
Saya mungkin harus menekankan: Semua metode yang saya hadapi tidak berpasangan satu sama lain. Tampaknya tidak ada cara yang masuk akal untuk memecahnya menjadi tas metode kelas statis yang lebih halus namun tetap multi-anggota.
sumber
Jawaban:
Saya pikir Anda memiliki dua masalah yang berkaitan erat satu sama lain.
Masalah-masalah ini dapat diperbaiki dengan menggabungkan hanya metode yang berhubungan secara logis ke dalam satu kelas statis dan memindahkan yang lain ke dalam kelas statis mereka sendiri. Berdasarkan domain masalah Anda, Anda dan tim Anda harus memutuskan kriteria apa yang akan Anda gunakan untuk memisahkan metode ke dalam kelas statis terkait.
Kekhawatiran dan kemungkinan solusi
Metode sebagian besar tidak terkait satu sama lain - masalah. Gabungkan metode terkait di bawah satu kelas statis dan pindahkan metode yang tidak terkait ke kelas statis mereka sendiri.
Metode tanpa keadaan eksplisit bertahan di doa - bukan masalah. Metode stateless adalah fitur, bukan bug. Keadaan statis sulit untuk diuji, dan seharusnya hanya digunakan jika Anda perlu mempertahankan keadaan di seluruh metode doa, tetapi ada cara yang lebih baik untuk melakukan itu seperti mesin negara dan
yield
kata kunci.Metode kecil - bukan masalah. - Metode harus kecil.
Metode masing-masing dikonsumsi oleh berbagai jenis yang tidak terkait - tidak masalah. Anda telah membuat metode umum yang dapat digunakan kembali di banyak tempat yang tidak terkait.
Kelas statis digunakan hanya sebagai namespace - bukan masalah. Ini adalah bagaimana metode statis digunakan. Jika gaya metode panggilan ini mengganggu Anda, coba gunakan metode ekstensi atau
using static
deklarasi.Pengidentifikasi kelas statis pada dasarnya tidak ada artinya - masalah . Ini tidak ada artinya karena pengembang memasukkan metode yang tidak terkait di dalamnya. Masukkan metode yang tidak terkait ke dalam kelas statis mereka sendiri dan beri mereka nama yang spesifik dan dapat dimengerti.
Ketika GLUM baru ditambahkan, baik (a) kelas "tas" ini disentuh (kesedihan SRP) - bukan masalah jika Anda mengikuti gagasan bahwa hanya metode yang berhubungan secara logis harus dalam satu kelas statis.
SRP
tidak dilanggar di sini, karena prinsip harus diterapkan untuk kelas atau metode. Tanggung jawab tunggal dari kelas statis berarti mengandung metode yang berbeda untuk satu "ide" umum. Gagasan itu dapat berupa fitur atau konversi, atau iterasi (LINQ), atau normalisasi data, atau validasi ...atau lebih jarang (b) kelas "tas" baru dibuat (lebih banyak tas) - tidak masalah. Kelas / kelas statis / fungsi - adalah alat (pengembang) kami, yang kami gunakan untuk merancang perangkat lunak. Apakah tim Anda memiliki batasan untuk menggunakan kelas? Berapa batas maksimum untuk "lebih banyak tas"? Pemrograman adalah semua tentang konteks, jika untuk solusi dalam konteks khusus Anda, Anda berakhir dengan 200 kelas statis yang dimengerti, secara logis ditempatkan dalam ruang nama / folder dengan hierarki logis - itu bukan masalah.
Penamaan meta tidak terhindarkan mengerikan, tidak standar, dan biasanya tidak konsisten secara internal, apakah itu Pembantu, Utilitas, atau apa pun - masalah. Berikan nama yang lebih baik yang menggambarkan perilaku yang diharapkan. Simpan hanya metode terkait dalam satu kelas, yang memberikan bantuan dalam penamaan yang lebih baik
sumber
A
dengan 100 kelas metode tunggal statis (dalam 100 file) daripada kelas statisA
dengan 100 metode dalam satu file.Math
kelas statis.Hanya merangkul konvensi bahwa kelas statis digunakan seperti ruang nama dalam situasi seperti ini di C #. Namespaces mendapatkan nama yang bagus, begitu juga kelas-kelas ini. The
using static
fitur C # 6 membuat hidup sedikit lebih mudah, juga.Nama-nama kelas yang berbau seperti
Helpers
sinyal bahwa metode harus dipecah menjadi kelas statis yang lebih baik, jika memungkinkan, tetapi salah satu asumsi Anda yang ditekankan adalah bahwa metode yang Anda hadapi adalah "pairwise unrelated", yang menyiratkan pemisahan menjadi satu kelas statis baru per metode yang ada. Itu mungkin baik, jikaSebagai contoh buat-buat,
Helpers.LoadImage
mungkin menjadi sesuatu sepertiFileSystemInteractions.LoadImage
.Namun, Anda bisa berakhir dengan metode-tas kelas statis. Beberapa cara ini bisa terjadi:
Penting untuk diingat bahwa tas-metode metode statis ini tidak terlalu jarang dalam basis kode C # nyata. Mungkin tidak patologis memiliki beberapa yang kecil .
Jika Anda benar-benar melihat keuntungan memiliki masing-masing metode seperti "fungsi bebas" dalam file sendiri (yang baik dan berharga jika Anda dengan jujur menilai bahwa itu sebenarnya menguntungkan pemeliharaan proyek Anda), Anda dapat mempertimbangkan membuat kelas statis seperti itu daripada statis. kelas parsial, mempekerjakan statis nama kelas mirip dengan bagaimana Anda akan sebuah namespace dan kemudian memakan melalui
using static
. Sebagai contoh:Program.cs
Foo / Bar.cs
Foo / Baz.cs
Flob / Wibble.cs
Flob / Goyangan.cs
sumber
Secara umum Anda tidak harus memiliki atau memerlukan "metode utilitas umum". Dalam logika bisnis Anda. Perhatikan baik-baik lagi dan letakkan di tempat yang cocok.
Jika Anda menulis perpustakaan matematika atau sesuatu, maka saya akan menyarankan, meskipun saya biasanya membenci mereka, Metode Ekstensi.
Anda dapat menggunakan Metode Ekstensi untuk menambahkan fungsi ke tipe data standar.
Misalnya Katakanlah saya memiliki fungsi umum MySort () bukan Helpers.MySort atau menambahkan ListOfMyThings.MySort baru saya dapat menambahkannya ke IEnumerable
sumber