ฉันพยายามปฏิบัติตาม Single Responsibility Principle (SRP) ให้มากที่สุดเท่าที่จะเป็นไปได้และคุ้นเคยกับรูปแบบที่แน่นอน (สำหรับ SRP เกี่ยวกับวิธีการ) อาศัยการมอบหมายอย่างมาก ฉันต้องการทราบว่าวิธีการนี้เป็นวิธีที่ดีหรือหากมีปัญหารุนแรงกับมัน
ตัวอย่างเช่นในการตรวจสอบอินพุตให้กับ constructor ฉันสามารถแนะนำวิธีต่อไปนี้ ( Stream
อินพุตเป็นแบบสุ่มอาจเป็นอะไรก็ได้)
private void CheckInput(Stream stream)
{
if(stream == null)
{
throw new ArgumentNullException();
}
if(!stream.CanWrite)
{
throw new ArgumentException();
}
}
วิธีนี้ (arguably) ทำมากกว่าหนึ่งอย่าง
- ตรวจสอบอินพุต
- โยนข้อยกเว้นที่แตกต่างกัน
เพื่อให้เป็นไปตาม SRP ฉันจึงเปลี่ยนตรรกะเป็น
private void CheckInput(Stream stream,
params (Predicate<Stream> predicate, Action action)[] inputCheckers)
{
foreach(var inputChecker in inputCheckers)
{
if(inputChecker.predicate(stream))
{
inputChecker.action();
}
}
}
สิ่งใดที่คาดคะเนว่าจะมีเพียงสิ่งเดียวเท่านั้น (ใช่ไหม): ตรวจสอบอินพุต สำหรับการตรวจสอบอินพุตและการโยนข้อยกเว้นที่เกิดขึ้นจริงฉันได้แนะนำวิธีการเช่น
bool StreamIsNull(Stream s)
{
return s == null;
}
bool StreamIsReadonly(Stream s)
{
return !s.CanWrite;
}
void Throw<TException>() where TException : Exception, new()
{
throw new TException();
}
และสามารถโทรCheckInput
เช่น
CheckInput(stream,
(this.StreamIsNull, this.Throw<ArgumentNullException>),
(this.StreamIsReadonly, this.Throw<ArgumentException>))
สิ่งนี้ดีกว่าตัวเลือกแรกเลยหรือฉันจะแนะนำความซับซ้อนที่ไม่จำเป็นหรือไม่? มีวิธีใดบ้างที่ฉันยังสามารถปรับปรุงรูปแบบนี้ได้ถ้าเป็นไปได้ทั้งหมด?
CheckInput
ยังคงทำหลายสิ่ง: มันซ้ำทั้งอาร์เรย์และการเรียกฟังก์ชันเพรดิเคตและเรียกใช้ฟังก์ชันการกระทำ นั่นไม่ใช่การละเมิด SRP หรือไม่?