ปัญหาบางอย่างกับ enum singletons:
มุ่งมั่นที่จะใช้กลยุทธ์การดำเนินงาน
โดยทั่วไปแล้ว "ซิงเกิล" หมายถึงกลยุทธ์การนำไปใช้งานไม่ใช่ข้อกำหนดของ API มันเป็นเรื่องยากมากที่Foo1.getInstance()
จะประกาศต่อสาธารณะว่ามันจะส่งคืนอินสแตนซ์เดียวกันเสมอ หากจำเป็นการดำเนินการของFoo1.getInstance()
สามารถพัฒนาตัวอย่างเช่นเพื่อส่งกลับหนึ่งอินสแตนซ์ต่อเธรด
กับFoo2.INSTANCE
เราต่อสาธารณชนประกาศว่ากรณีนี้เป็นเช่นและมีโอกาสที่จะเปลี่ยนแปลง กลยุทธ์การดำเนินงานของการมีอินสแตนซ์เดียวมีการเปิดเผยและมุ่งมั่น
ปัญหานี้ไม่ทำให้หมดอำนาจ ตัวอย่างเช่นFoo2.INSTANCE.doo()
สามารถพึ่งพาอ็อบเจ็กต์ตัวช่วยโลคัลเธรดเพื่อให้มีอินสแตนซ์ต่อเธรดได้อย่างมีประสิทธิภาพ
การขยายคลาส Enum
Foo2
Enum<Foo2>
ขยายชั้นยอด โดยปกติเราต้องการหลีกเลี่ยงคลาสที่ยอดเยี่ยม โดยเฉพาะอย่างยิ่งในกรณีนี้ผู้บังคับการระดับสูงFoo2
ไม่มีส่วนเกี่ยวข้องกับสิ่งที่Foo2
ควรจะเป็น นั่นคือมลพิษต่อลำดับชั้นชนิดของแอปพลิเคชันของเรา ถ้าเราต้องการซุปเปอร์คลาสจริงๆโดยปกติแล้วจะเป็นคลาสแอปพลิเคชัน แต่เราไม่สามารถทำได้Foo2
ซูเปอร์คลาสของจะได้รับการแก้ไข
Foo2
สืบทอดเมธอดอินสแตนซ์ตลกบางอย่างเช่นname(), cardinal(), compareTo(Foo2)
ซึ่งสร้างความสับสนให้กับFoo2
ผู้ใช้ Foo2
ไม่สามารถมีname()
วิธีการของตัวเองแม้ว่าวิธีการนั้นเป็นที่ต้องการในFoo2
ส่วนต่อประสานของ
Foo2
ยังมีวิธีการคงที่ตลกบางอย่าง
public static Foo2[] values() { ... }
public static Foo2 valueOf(String name) { ... }
public static <T extends Enum<T>> T valueOf(Class<T> enumType, String name)
ซึ่งดูเหมือนจะไร้สาระต่อผู้ใช้ ซิงเกิลตันไม่ควรมีวิธีคงที่ pulbic อย่างไรก็ตาม (นอกเหนือจากgetInstance()
)
Serializability
มันเป็นเรื่องธรรมดามากสำหรับซิงเกิลที่จะเป็นมลรัฐ โดยทั่วไปแล้วซิงเกิลเหล่านี้ไม่ควรต่อเนื่องกันได้ ฉันไม่สามารถนึกถึงตัวอย่างที่เป็นจริงใด ๆ ที่ทำให้การขนส่งซิงเกิลที่เป็นรัฐจาก VM ไปยัง VM อื่น ซิงเกิลตันหมายถึง "เอกสิทธิ์ภายใน VM" ไม่ใช่ "เอกสิทธิ์ในเอกภพ"
หากการทำให้เป็นอนุกรมนั้นสมเหตุสมผลสำหรับ singleton stateful Singleton ควรระบุอย่างชัดเจนและแม่นยำว่าการ deserialize singleton ใน VM อื่นที่มี singleton ชนิดเดียวกันนั้นมีอยู่จริง
Foo2
มุ่งมั่นกับกลยุทธ์การทำให้เป็นอันดับ / การดีซีเรียลไลเซชันแบบง่ายๆโดยอัตโนมัติ นั่นเป็นเพียงอุบัติเหตุที่รอให้เกิดขึ้น หากเรามีโครงสร้างข้อมูลอ้างอิงแนวคิดของตัวแปรสถานะFoo2
ใน VM1 ที่ t1 ผ่านการทำให้เป็นอนุกรม / การดีซีเรียลไลเซชันค่าจะกลายเป็นค่าที่แตกต่าง - มูลค่าของตัวแปรเดียวกันFoo2
ใน VM2 ที่ t2 ทำให้เกิดข้อผิดพลาดในการตรวจจับยาก ข้อผิดพลาดนี้จะไม่เกิดขึ้นกับคนที่ไม่สามารถตั้งค่าได้Foo1
อย่างเงียบ ๆ
ข้อ จำกัด ของการเข้ารหัส
มีสิ่งต่าง ๆ ที่สามารถทำได้ในชั้นเรียนปกติ แต่ต้องห้ามในenum
ชั้นเรียน ตัวอย่างเช่นการเข้าถึงฟิลด์คงที่ในตัวสร้าง โปรแกรมเมอร์จะต้องระมัดระวังมากขึ้นเนื่องจากเขาทำงานในชั้นเรียนพิเศษ
ข้อสรุป
โดย piggybacking บน enum เราบันทึกโค้ดไว้ 2 บรรทัด; แต่ราคาสูงเกินไปเราต้องแบกกระเป๋าและข้อ จำกัด ทั้งหมดของ enums เราได้รับมรดก "คุณสมบัติ" ของ enum ที่มีผลกระทบโดยไม่ตั้งใจ ข้อได้เปรียบที่ถูกกล่าวหาเพียงอย่างเดียว - การต่ออนุกรมอัตโนมัติ - กลายเป็นข้อเสีย