Bu API işlevi var:
public ResultEnum DoSomeAction(string a, string b, DateTime c, OtherEnum d,
string e, string f, out Guid code)
Sevmiyorum. Çünkü parametre sırası gereksiz yere önemli hale gelir. Yeni alanlar eklemek zorlaşıyor. Nelerin geçtiğini görmek daha zor. Alt fonksiyonlardaki tüm parametreleri geçirmenin başka bir yükünü oluşturduğu için yöntemi daha küçük parçalara yeniden düzenlemek daha zordur. Kodun okunması daha zordur.
En açık fikirle geldim: verileri çevreleyen bir nesne var ve her parametreyi tek tek geçmek yerine onu iletiyor. İşte ben geldim:
public class DoSomeActionParameters
{
public string A;
public string B;
public DateTime C;
public OtherEnum D;
public string E;
public string F;
}
Bu, API beyanımı şu şekilde düşürdü:
public ResultEnum DoSomeAction(DoSomeActionParameters parameters, out Guid code)
Güzel. Çok masum görünüyor ama aslında büyük bir değişiklik getirdik: değişebilirlik getirdik. Çünkü daha önce yaptığımız şey aslında anonim değişmez bir nesneyi geçmekti: yığın üzerindeki fonksiyon parametreleri. Şimdi çok değişebilen yeni bir sınıf yarattık. Arayanın durumunu değiştirme yeteneğini yarattık . Bu berbat. Şimdi nesnemin değişmez olmasını istiyorum, ne yapmalıyım?
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
}
}
Gördüğünüz gibi aslında asıl sorunumu yeniden yarattım: çok fazla parametre. Bu yolun gitmediği açık. Ne ben yapacağım? Böyle bir değişmezliği elde etmek için son seçenek şöyle bir "salt okunur" yapı kullanmaktır:
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;
}
Bu, çok fazla parametreye sahip yapıcılardan kaçınmamıza ve değişmezliğe ulaşmamıza izin verir. Aslında tüm sorunları düzeltir (parametre sıralaması vb.). Hala:
- Herkes (FXCop ve Jon Skeet dahil) kamuya açık alanların ifşa edilmesinin kötü olduğunu kabul eder .
- Eric Lippert ve arkadaşları değişmezlik için salt okunur alanlara güvenmenin bir yalan olduğunu söylüyor .
İşte o zaman kafam karıştı ve bu soruyu yazmaya karar verdi: C # 'de değişebilirliğe neden olmadan "çok fazla parametre" probleminden kaçınmanın en kolay yolu nedir? Bu amaç için salt okunur bir yapı kullanmak, ancak yine de kötü bir API tasarımına sahip olmak mümkün müdür?
AÇIKLAMALAR:
- Tek bir sorumluluk ilkesinin ihlal edilmediğini varsayalım. Orijinal durumumda, fonksiyon sadece verilen parametreleri tek bir DB kaydına yazar.
- Verilen işleve özel bir çözüm aramıyorum. Bu tür sorunlara genel bir yaklaşım arıyorum. Ben özellikle değişebilirlik ya da korkunç bir tasarım getirmeden "çok fazla parametre" sorunu çözmek ilgilendi.
GÜNCELLEME
Burada verilen cevapların farklı avantajları / dezavantajları vardır. Bu yüzden bunu bir topluluk wikisine dönüştürmek istiyorum. Ben kod örneği ve Artıları / Eksileri ile her cevap gelecekte benzer sorunlar için iyi bir rehber olacağını düşünüyorum. Şimdi nasıl yapılacağını öğrenmeye çalışıyorum.
DoSomeActionParameters
yöntem çağrısından sonra atılacak olan bir ıskarta nesnesi olduğunu düşünerek bunun nasıl bir sorun olduğunu göremiyorum .