Saya memiliki fungsi API ini:
public ResultEnum DoSomeAction(string a, string b, DateTime c, OtherEnum d,
string e, string f, out Guid code)
Saya tidak suka itu. Karena urutan parameter menjadi tidak penting. Semakin sulit untuk menambahkan bidang baru. Lebih sulit untuk melihat apa yang sedang diedarkan. Lebih sulit untuk mengubah metode menjadi bagian-bagian yang lebih kecil karena ini menciptakan overhead lain untuk melewatkan semua parameter dalam sub fungsi. Kode lebih sulit dibaca.
Saya datang dengan ide yang paling jelas: memiliki objek merangkum data dan menyebarkannya alih-alih melewati setiap parameter satu per satu. Inilah yang saya pikirkan:
public class DoSomeActionParameters
{
public string A;
public string B;
public DateTime C;
public OtherEnum D;
public string E;
public string F;
}
Itu mengurangi deklarasi API saya ke:
public ResultEnum DoSomeAction(DoSomeActionParameters parameters, out Guid code)
Bagus. Terlihat sangat polos tapi kami benar-benar memperkenalkan perubahan besar: kami memperkenalkan kemampuan berubah-ubah. Karena apa yang sebelumnya telah kami lakukan sebenarnya untuk melewatkan objek abadi anonim: parameter fungsi pada stack. Sekarang kami membuat kelas baru yang sangat bisa berubah. Kami menciptakan kemampuan untuk memanipulasi keadaan penelepon . Itu menyebalkan. Sekarang saya ingin objek saya tidak berubah, apa yang harus saya lakukan?
public class DoSomeActionParameters
{
public string A { get; private set; }
public string B { get; private set; }
public DateTime C { get; private set; }
public OtherEnum D { get; private set; }
public string E { get; private set; }
public string F { get; private set; }
public DoSomeActionParameters(string a, string b, DateTime c, OtherEnum d,
string e, string f)
{
this.A = a;
this.B = b;
// ... tears erased the text here
}
}
Seperti yang Anda lihat, saya benar-benar menciptakan kembali masalah asli saya: terlalu banyak parameter. Sudah jelas bahwa itu bukan cara untuk pergi. Apa yang akan aku lakukan? Opsi terakhir untuk mencapai ketidakberubahan tersebut adalah dengan menggunakan struct "readonly" seperti ini:
public struct DoSomeActionParameters
{
public readonly string A;
public readonly string B;
public readonly DateTime C;
public readonly OtherEnum D;
public readonly string E;
public readonly string F;
}
Itu memungkinkan kita untuk menghindari konstruktor dengan terlalu banyak parameter dan mencapai kekekalan. Sebenarnya itu memperbaiki semua masalah (pemesanan parameter dll). Namun:
- Semua orang (termasuk FXCop & Jon Skeet) setuju bahwa mengekspos bidang publik adalah buruk .
- Eric Lippert dkk mengatakan mengandalkan bidang yang hanya bisa dibaca untuk kekekalan adalah dusta .
Saat itulah saya menjadi bingung dan memutuskan untuk menulis pertanyaan ini: Apa cara paling mudah dalam C # untuk menghindari masalah "terlalu banyak parameter" tanpa memperkenalkan kemampuan berubah-ubah? Apakah mungkin untuk menggunakan struct hanya baca untuk tujuan itu dan belum memiliki desain API yang buruk?
KLARIFIKASI:
- Harap asumsikan tidak ada pelanggaran terhadap prinsip tanggung jawab tunggal. Dalam kasus asli saya fungsi hanya menulis parameter yang diberikan ke catatan DB tunggal.
- Saya tidak mencari solusi spesifik untuk fungsi yang diberikan. Saya mencari pendekatan umum untuk masalah seperti itu. Saya secara khusus tertarik untuk memecahkan masalah "terlalu banyak parameter" tanpa memperkenalkan kemampuan berubah-ubah atau desain yang mengerikan.
MEMPERBARUI
Jawaban yang diberikan di sini memiliki kelebihan / kekurangan yang berbeda. Karenanya saya ingin mengonversikan ini ke wiki komunitas. Saya pikir setiap jawaban dengan contoh kode dan Pro / Kontra akan menjadi panduan yang baik untuk masalah yang sama di masa depan. Saya sekarang mencoba mencari tahu bagaimana melakukannya.
DoSomeActionParameters
adalah objek sekali pakai, yang akan dibuang setelah pemanggilan metode.