ในระบบของฉันฉันมักทำงานกับรหัสสนามบิน ( "YYZ", "LAX", "SFO"ฯลฯ ) พวกเขามักจะอยู่ในรูปแบบเดียวกันแน่นอน (3 ตัวอักษรแสดงเป็นตัวพิมพ์ใหญ่) โดยทั่วไประบบจะจัดการกับ 25-50 ของรหัส (ต่างกัน) ต่อคำขอ API ด้วยการจัดสรรรวมกว่าพันรายการระบบจะส่งผ่านแอปพลิเคชันของเราหลายเลเยอร์และเปรียบเทียบกับความเท่าเทียมกันบ่อยครั้ง
เราเริ่มต้นด้วยการส่งสายไปรอบ ๆ ซึ่งใช้งานได้ดี แต่เราก็สังเกตเห็นข้อผิดพลาดในการเขียนโปรแกรมจำนวนมากได้อย่างรวดเร็วโดยการส่งรหัสผิดไปที่ไหนสักแห่งคาดว่ารหัส 3 หลัก นอกจากนี้เรายังพบปัญหาที่เราควรทำการเปรียบเทียบแบบตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ แต่ไม่ได้ทำให้เกิดข้อบกพร่อง
จากนี้ฉันตัดสินใจที่จะหยุดการส่งผ่านสายไปรอบ ๆ และสร้างAirportชั้นเรียนซึ่งมีตัวสร้างเดียวที่ใช้และตรวจสอบรหัสสนามบิน
public sealed class Airport
{
public Airport(string code)
{
if (code == null)
{
throw new ArgumentNullException(nameof(code));
}
if (code.Length != 3 || !char.IsLetter(code[0])
|| !char.IsLetter(code[1]) || !char.IsLetter(code[2]))
{
throw new ArgumentException(
"Must be a 3 letter airport code.",
nameof(code));
}
Code = code.ToUpperInvariant();
}
public string Code { get; }
public override string ToString()
{
return Code;
}
private bool Equals(Airport other)
{
return string.Equals(Code, other.Code);
}
public override bool Equals(object obj)
{
return obj is Airport airport && Equals(airport);
}
public override int GetHashCode()
{
return Code?.GetHashCode() ?? 0;
}
public static bool operator ==(Airport left, Airport right)
{
return Equals(left, right);
}
public static bool operator !=(Airport left, Airport right)
{
return !Equals(left, right);
}
}
สิ่งนี้ทำให้รหัสของเราง่ายต่อการเข้าใจและเราทำให้การตรวจสอบความเท่าเทียมกันของเราง่ายขึ้น, การใช้พจนานุกรม / การตั้งค่า ตอนนี้เรารู้แล้วว่าหากวิธีการของเรายอมรับAirportอินสแตนซ์ที่มันจะทำงานในแบบที่เราคาดไว้มันก็ทำให้การตรวจสอบวิธีการของเราง่ายขึ้นเป็นการตรวจสอบการอ้างอิงแบบ null
อย่างไรก็ตามสิ่งที่ฉันสังเกตเห็นคือการรวบรวมขยะกำลังทำงานอยู่บ่อยครั้งมากขึ้นซึ่งฉันติดตามไปที่Airportการรวบรวมจำนวนมาก
วิธีการแก้ปัญหาของฉันไปนี้คือการแปลงเป็นclass structส่วนใหญ่เป็นเพียงการเปลี่ยนแปลงคำหลักยกเว้นGetHashCodeและToString:
public override string ToString()
{
return Code ?? string.Empty;
}
public override int GetHashCode()
{
return Code?.GetHashCode() ?? 0;
}
เพื่อจัดการกรณีที่default(Airport)มีการใช้
คำถามของฉัน:
การสร้าง
Airportคลาสหรือโครงสร้างเป็นคำตอบที่ดีโดยทั่วไปหรือฉันกำลังแก้ไขปัญหาที่ผิด / แก้ไขด้วยวิธีที่ไม่ถูกต้องด้วยการสร้างประเภทหรือไม่ หากไม่ใช่วิธีที่ดีวิธีแก้ปัญหาที่ดีกว่าคืออะไรแอปพลิเคชันของฉันควรจัดการกับอินสแตนซ์ที่
default(Airport)ใช้งานอย่างไร ประเภทของdefault(Airport)แอพพลิเคชั่นของฉันไร้สาระดังนั้นฉันจึงทำif (airport == default(Airport) { throw ... }ในสถานที่ซึ่งการได้รับอินสแตนซ์ของAirport(และCodeคุณสมบัติของมัน) มีความสำคัญต่อการดำเนินการ
หมายเหตุ: ฉันได้ตรวจสอบคำถามC # / VB struct - วิธีการหลีกเลี่ยงกรณีที่มีค่าเริ่มต้นเป็นศูนย์ซึ่งถือว่าไม่ถูกต้องสำหรับโครงสร้างที่กำหนด? และใช้ struct หรือไม่ก่อนถามคำถามของฉัน แต่ฉันคิดว่าคำถามของฉันแตกต่างกันพอที่จะรับประกันการโพสต์ของตัวเอง
default(Airport)ปัญหาได้ก็คือเพียงแค่ไม่อนุญาตให้ใช้อินสแตนซ์เริ่มต้น คุณสามารถทำได้โดยการเขียนคอนสตรัคเตอร์แบบไร้พารามิเตอร์แล้วโยนInvalidOperationExceptionหรือNotImplementedExceptionลงไป