การปฏิบัติส่วนตัวของฉันคือต่อไปนี้:
- ฉันไม่ชอบฟังก์ชั่นที่มีจุดออกหลายแห่งฉันพบว่ามันยากที่จะรักษาและติดตามบางครั้งการแก้ไขโค้ดอาจทำให้ตรรกะภายในเสียหายได้ เมื่อเป็นการคำนวณที่ซับซ้อนฉันจะสร้างค่าตอบแทนที่จุดเริ่มต้นและส่งคืนในตอนท้าย สิ่งนี้บังคับให้ฉันต้องติดตามแต่ละ if-else สวิตช์ ฯลฯ เส้นทางอย่างระมัดระวังตั้งค่าอย่างถูกต้องในตำแหน่งที่เหมาะสม ฉันยังใช้เวลาเล็กน้อยในการตัดสินใจว่าจะตั้งค่าส่งคืนเริ่มต้นหรือไม่ปล่อยให้มันเป็นค่าเริ่มต้น วิธีนี้ยังช่วยเมื่อตรรกะหรือประเภทค่าตอบแทนหรือความหมายเปลี่ยนแปลง
ตัวอย่างเช่น:
public bool myFunction()
{
// First parameter loading
String myString = getString();
// Location of "quick exits", see the second example
// ...
// declaration of external resources that MUST be released whatever happens
// ...
// the return variable (should think about giving it a default value or not)
// if you have no default value, declare it final! You will get compiler
// error when you try to set it multiple times or leave uninitialized!
bool didSomething = false;
try {
if (myString != null)
{
myString = "Name " + myString;
// Do something more here...
didSomething = true;
} else {
// get other parameters and data
if ( other conditions apply ) {
// do something else
didSomething = true;
}
}
// Edit: previously forgot the most important advantage of this version
// *** HOUSEKEEPING!!! ***
} finally {
// this is the common place to release all resources, reset all state variables
// Yes, if you use try-finally, you will get here from any internal returns too.
// As I said, it is only my taste that I like to have one, straightforward path
// leading here, and this works even if you don't use the try-finally version.
}
return didSomething;
}
- ข้อยกเว้นเดียวเท่านั้น: "ออกอย่างรวดเร็ว" ที่เริ่มต้น (หรือในบางกรณีภายในกระบวนการ) หากตรรกะการคำนวณจริงไม่สามารถจัดการการรวมกันของพารามิเตอร์อินพุตและสถานะภายในหรือมีวิธีแก้ปัญหาอย่างง่ายโดยไม่ต้องใช้อัลกอริทึมมันไม่ได้ช่วยให้มีการห่อหุ้มโค้ดทั้งหมด (บางครั้งลึก) หากบล็อก นี่เป็น "สถานะพิเศษ" ไม่ใช่ส่วนหนึ่งของตรรกะหลักดังนั้นฉันต้องออกจากการคำนวณทันทีที่ฉันตรวจพบ ในกรณีนี้ไม่มีสาขาอื่นในสภาวะปกติการดำเนินการจะดำเนินต่อไป (แน่นอนว่า "สถานะพิเศษ" จะแสดงออกมาได้ดีกว่าโดยการโยนข้อยกเว้น แต่บางครั้งก็เป็น overkill)
ตัวอย่างเช่น:
public bool myFunction()
{
String myString = getString();
if (null == myString)
{
// there is nothing to do if myString is null
return false;
}
myString = "Name " + myString;
// Do something more here...
// not using return value variable now, because the operation is straightforward.
// if the operation is complex, use the variable as the previous example.
return true;
}
กฎ "one exit" ยังช่วยเมื่อการคำนวณต้องการทรัพยากรภายนอกที่คุณต้องปล่อยหรือระบุว่าคุณต้องรีเซ็ตก่อนออกจากฟังก์ชัน บางครั้งมีการเพิ่มภายหลังในระหว่างการพัฒนา ด้วยการออกหลายครั้งในอัลกอริทึมจึงเป็นการยากที่จะขยายสาขาทั้งหมดอย่างถูกต้อง (และหากมีข้อยกเว้นเกิดขึ้นควรปล่อย / รีเซ็ตในบล็อกในที่สุดเช่นกันเพื่อหลีกเลี่ยงผลข้างเคียงในกรณีพิเศษที่หายาก ... )
กรณีของคุณดูเหมือนจะตกอยู่ในหมวดหมู่ "ออกอย่างรวดเร็วก่อนที่จะทำงานจริง" และฉันจะเขียนมันเหมือนเวอร์ชัน 2 ตัวอย่างของคุณ