ฉันมีคลาสที่เต็มไปด้วยฟังก์ชันยูทิลิตี้ การสร้างอินสแตนซ์ของอินสแตนซ์นั้นไม่สมเหตุสมผล แต่ฉันยังต้องการเรียกวิธีการของมัน วิธีที่ดีที่สุดในการจัดการกับปัญหานี้คืออะไร? ชั้นคง? บทคัดย่อ?
ฉันมีคลาสที่เต็มไปด้วยฟังก์ชันยูทิลิตี้ การสร้างอินสแตนซ์ของอินสแตนซ์นั้นไม่สมเหตุสมผล แต่ฉันยังต้องการเรียกวิธีการของมัน วิธีที่ดีที่สุดในการจัดการกับปัญหานี้คืออะไร? ชั้นคง? บทคัดย่อ?
คำตอบ:
ตัวสร้างส่วนตัวและเมธอดแบบคงที่บนคลาสที่ทำเครื่องหมายเป็นขั้นสุดท้าย
อ้างอิงจากหนังสือ"Effective Java" :
ข้อ 4: บังคับใช้การไม่หยุดนิ่งด้วยตัวสร้างส่วนตัว
- การพยายามบังคับใช้การไม่หยุดนิ่งโดยการสร้างบทคัดย่อของคลาสไม่ได้ผล
- ตัวสร้างเริ่มต้นจะถูกสร้างขึ้นเฉพาะในกรณีที่คลาสไม่มีตัวสร้างที่ชัดเจนดังนั้นคลาสสามารถทำให้ไม่คงที่โดยการรวมคอนสตรัคเตอร์ส่วนตัว:
// Noninstantiable utility class
public class UtilityClass
{
// Suppress default constructor for noninstantiability
private UtilityClass() {
throw new AssertionError();
}
}
เนื่องจากตัวสร้างที่ชัดเจนเป็นแบบส่วนตัวจึงไม่สามารถเข้าถึงได้จากภายนอกคลาส AssertionError ไม่จำเป็นต้องใช้อย่างเคร่งครัด แต่จะให้การประกันในกรณีที่ตัวสร้างถูกเรียกโดยไม่ได้ตั้งใจจากภายในคลาส รับประกันได้ว่าคลาสจะไม่ถูกสร้างอินสแตนซ์ไม่ว่าในสถานการณ์ใด ๆ สำนวนนี้มีความขัดแย้งเล็กน้อยเนื่องจากตัวสร้างถูกจัดเตรียมไว้อย่างชัดเจนเพื่อไม่ให้เรียกใช้ ดังนั้นจึงควรใส่ความคิดเห็นดังที่แสดงไว้ด้านบน
ผลข้างเคียงสำนวนนี้ยังป้องกันไม่ให้คลาสย่อย ตัวสร้างทั้งหมดต้องเรียกใช้ตัวสร้างคลาสระดับสูงอย่างชัดเจนหรือโดยปริยายและคลาสย่อยจะไม่มีตัวสร้างระดับซุปเปอร์คลาสที่สามารถเข้าถึงได้เพื่อเรียกใช้
AssertionError
มากกว่าทางเลือกอื่น ๆ เช่นIllegalStateException
, UnsupportedOperationException
etc?
เสียงเหมือนคุณมีระดับสาธารณูปโภคคล้ายกับjava.lang.Math
แนวทางมีคลาสสุดท้ายที่มีตัวสร้างส่วนตัวและวิธีการแบบคงที่
แต่ระวังว่าสิ่งนี้ทำเพื่อความสามารถในการทดสอบฉันขอแนะนำให้อ่านบทความนี้
Static Methods คือ Death to Testability
เพียงเพื่อว่ายทวนน้ำสมาชิกและชั้นเรียนคงไม่เข้าร่วมใน OO ดังนั้นจึงเป็นสิ่งชั่วร้าย ไม่ไม่ใช่ความชั่วร้าย แต่อย่างจริงจังฉันขอแนะนำชั้นเรียนปกติที่มีรูปแบบซิงเกิลตันสำหรับการเข้าถึง วิธีนี้หากคุณจำเป็นต้องลบล้างพฤติกรรมไม่ว่าในกรณีใด ๆ บนท้องถนนจะไม่ใช่การปรับเปลี่ยนหลัก OO เป็นเพื่อนของคุณ :-)
$ .02 ของฉัน
แสดงความคิดเห็นเกี่ยวกับอาร์กิวเมนต์ "ตัวสร้างส่วนตัว": มาเถอะนักพัฒนาไม่ได้โง่ขนาดนั้น แต่พวกเขาขี้เกียจ สร้างวัตถุจากนั้นเรียกวิธีการคงที่? จะไม่เกิดขึ้น
อย่าใช้เวลามากเกินไปเพื่อให้แน่ใจว่าชั้นเรียนของคุณจะไม่ถูกนำไปใช้ในทางที่ผิด มีศรัทธาต่อเพื่อนร่วมงานของคุณ และยังมีวิธีใช้ชั้นเรียนในทางที่ผิดเสมอไม่ว่าคุณจะปกป้องชั้นเรียนอย่างไร สิ่งเดียวที่ไม่สามารถนำไปใช้ในทางที่ผิดคือสิ่งที่ไร้ประโยชน์โดยสิ้นเชิง
static
มีจุดในการประกาศคลาสเป็นไม่ได้ เพียงแค่ประกาศวิธีการstatic
และเรียกใช้จากชื่อคลาสตามปกติเช่นคลาสMathของ Java
นอกจากนี้แม้ว่าจะไม่จำเป็นต้องทำให้ตัวสร้างเป็นแบบส่วนตัว แต่ก็เป็นความคิดที่ดีที่จะทำเช่นนั้น การทำเครื่องหมายตัวสร้างเป็นแบบส่วนตัวจะป้องกันไม่ให้บุคคลอื่นสร้างอินสแตนซ์ของคลาสของคุณจากนั้นเรียกใช้วิธีการแบบคงที่จากอินสแตนซ์เหล่านั้น (การเรียกเหล่านี้ทำงานเหมือนกันทุกประการใน Java ซึ่งเป็นเพียงการทำให้เข้าใจผิดและส่งผลเสียต่อการอ่านโค้ดของคุณ)
คุณสามารถใช้คำอธิบายประกอบ @UtilityClass จาก lombok https://projectlombok.org/features/experimental/UtilityClass