ฉันพิจารณาfinal
ในพารามิเตอร์เมธอดและตัวแปรโลคัลเพื่อเป็นจุดรบกวนของโค้ด การประกาศเมธอด Java สามารถค่อนข้างยาว (โดยเฉพาะกับ generics) - ไม่จำเป็นต้องทำให้อีกต่อไป
หากการทดสอบหน่วยจะถูกเขียนอย่างถูกต้อง, การกำหนดค่าพารามิเตอร์ที่เป็น "อันตราย" จะถูกหยิบขึ้นมาดังนั้นจึงไม่ควรที่จริงจะมีปัญหา ความคมชัดของภาพมีความสำคัญมากกว่าการหลีกเลี่ยงไปได้ข้อผิดพลาดที่ไม่ได้หยิบขึ้นมาเพราะการทดสอบหน่วยของคุณมีความคุ้มครองไม่เพียงพอ
เครื่องมือเช่น FindBugs และ CheckStyle ที่สามารถกำหนดค่าให้ทำลายโครงสร้างได้หากการมอบหมายให้กับพารามิเตอร์หรือตัวแปรในตัวเครื่องหากคุณใส่ใจในสิ่งต่าง ๆ อย่างลึกซึ้ง
แน่นอนถ้าคุณต้องการทำให้มันเป็นที่สิ้นสุดตัวอย่างเช่นเพราะคุณกำลังใช้ค่าในคลาสที่ไม่ระบุชื่อดังนั้นก็ไม่มีปัญหานั่นเป็นวิธีการแก้ปัญหาที่ง่ายที่สุด
นอกเหนือจากผลกระทบที่ชัดเจนของการเพิ่มคำหลักพิเศษลงในพารามิเตอร์ของคุณและด้วยเหตุนี้ IMHO จึงพรางคำเหล่านั้นการเพิ่มขั้นสุดท้ายให้กับพารามิเตอร์วิธีสามารถทำให้รหัสในวิธีการเนื้อความอ่านง่ายขึ้นซึ่งทำให้รหัสแย่ลง - เป็น "ดี" รหัส จะต้องสามารถอ่านได้และเรียบง่ายที่สุดเท่าที่จะทำได้ สำหรับตัวอย่างที่วางแผนไว้บอกว่าฉันมีวิธีการที่จำเป็นต้องใช้กรณีศึกษาอย่างไม่รู้สึกตัว
โดยไม่ต้องfinal
:
public void doSomething(String input) {
input = input.toLowerCase();
// do a few things with input
}
ง่าย สะอาด ทุกคนรู้ว่าเกิดอะไรขึ้น
ตอนนี้ด้วย 'final' ตัวเลือก 1:
public void doSomething(final String input) {
final String lowercaseInput = input.toLowerCase();
// do a few things with lowercaseInput
}
ในขณะที่การทำให้พารามิเตอร์final
หยุด coder การเพิ่มรหัสเพิ่มเติมจากที่คิดว่าเขากำลังทำงานกับค่าเดิมมีความเสี่ยงที่เท่าเทียมกันที่รหัสต่อไปอาจใช้input
แทนlowercaseInput
ซึ่งไม่ควรและที่ไม่สามารถป้องกันเพราะคุณสามารถ ' ไม่นำออกจากขอบเขต (หรือแม้กระทั่งมอบหมายnull
ให้input
หากสิ่งนั้นจะช่วยได้อยู่ดี)
ด้วย 'final' ตัวเลือก 2:
public void doSomething(final String input) {
// do a few things with input.toLowerCase()
}
ตอนนี้เราเพิ่งสร้างรหัสเสียงให้มากขึ้นและนำเสนอประสิทธิภาพที่ยอดเยี่ยมในการเรียกใช้toLowerCase()
n ครั้ง
ด้วย 'final' ตัวเลือก 3:
public void doSomething(final String input) {
doSomethingPrivate(input.toLowerCase());
}
/** @throws IllegalArgumentException if input not all lower case */
private void doSomethingPrivate(final String input) {
if (!input.equals(input.toLowerCase())) {
throw new IllegalArgumentException("input not lowercase");
}
// do a few things with input
}
พูดคุยเกี่ยวกับเสียงรหัส นี่คือซากรถไฟ เรามีวิธีการใหม่ซึ่งเป็นบล็อกข้อยกเว้นที่จำเป็นเนื่องจากรหัสอื่นอาจเรียกใช้อย่างไม่ถูกต้อง ทดสอบหน่วยเพิ่มเติมเพื่อให้ครอบคลุมข้อยกเว้น ทั้งหมดเพื่อหลีกเลี่ยงหนึ่งบรรทัดที่ง่ายและ IMHO ที่เป็นที่นิยมและไม่เป็นอันตราย
นอกจากนี้ยังมีปัญหาที่วิธีการไม่ควรยาวจนคุณไม่สามารถมองเห็นได้ง่ายและรู้ได้ทันทีว่ามีการกำหนดพารามิเตอร์ให้
ฉันคิดว่ามันเป็นแนวปฏิบัติที่ดี / ถ้าคุณกำหนดให้กับพารามิเตอร์ที่คุณทำมันทุกต้นในวิธีการโดยเฉพาะอย่างยิ่งบรรทัดแรกหรือตรงหลังจากการตรวจสอบอินพุตขั้นพื้นฐานอย่างมีประสิทธิภาพแทนที่มันสำหรับวิธีการทั้งหมดซึ่งมีผลสอดคล้องภายใน วิธี. ผู้อ่านรู้ว่าคาดหวังว่าการมอบหมายใด ๆ จะชัดเจน (ใกล้กับการประกาศลายเซ็น) และในสถานที่ที่สอดคล้องกันซึ่งช่วยลดปัญหาที่เพิ่มสุดท้ายพยายามหลีกเลี่ยงอย่างมาก ที่จริงฉันไม่ค่อยได้กำหนดพารามิเตอร์ แต่ถ้าฉันทำฉันมักจะทำที่ด้านบนของวิธีการ
โปรดทราบว่าfinal
ในตอนแรกไม่ได้ปกป้องคุณอย่างที่คุณเห็น
public void foo(final Date date) {
date.setTime(0);
// code that uses date
}
final
ไม่ได้ป้องกันคุณอย่างสมบูรณ์เว้นแต่ประเภทพารามิเตอร์จะเป็นแบบดั้งเดิมหรือไม่เปลี่ยนรูป