ฉันไม่เคยพบคำตอบที่ดีสำหรับคำถามง่ายๆเหล่านี้เกี่ยวกับคลาสตัวช่วย / ยูทิลิตี้:
เหตุใดฉันจึงต้องสร้างซิงเกิลตัน (ไร้สัญชาติ) แทนที่จะใช้วิธีการแบบคงที่
เหตุใดจึงจำเป็นต้องใช้อินสแตนซ์วัตถุหากวัตถุไม่มีสถานะ
ฉันไม่เคยพบคำตอบที่ดีสำหรับคำถามง่ายๆเหล่านี้เกี่ยวกับคลาสตัวช่วย / ยูทิลิตี้:
เหตุใดฉันจึงต้องสร้างซิงเกิลตัน (ไร้สัญชาติ) แทนที่จะใช้วิธีการแบบคงที่
เหตุใดจึงจำเป็นต้องใช้อินสแตนซ์วัตถุหากวัตถุไม่มีสถานะ
คำตอบ:
บ่อยครั้งที่เสื้อกล้ามถูกใช้เพื่อแนะนำสถานะระดับโลกบางอย่างให้กับแอปพลิเคชัน (พูดตามตรงบ่อยเกินความจำเป็น แต่นั่นเป็นหัวข้อสำหรับอีกครั้ง)
อย่างไรก็ตามมีบางกรณีที่แม้แต่คนโสดไร้สัญชาติก็มีประโยชน์:
lock
หรือsynchronized
คำสั่งJavaToolkit.getDefaultToolkit()
เมธอดใน Java จะส่งคืน Singleton ที่มีประเภทที่แน่นอนขึ้นอยู่กับระบบDBNull.Value
ใน C #ฉันจะได้เห็นกรณีสำหรับไร้สัญชาติเดี่ยวถูกนำมาใช้แทนวิธีการคงระดับคือสำหรับการพึ่งพาการฉีด
หากคุณมีคลาสผู้ช่วยของฟังก์ชันยูทิลิตี้ที่คุณใช้โดยตรงมันจะสร้างการอ้างอิงที่ซ่อนอยู่ คุณไม่สามารถควบคุมได้ว่าใครสามารถใช้งานได้หรือที่ไหน การใส่คลาสตัวช่วยเดียวกันนั้นผ่านอินสแตนซ์ซิงเกิลตันที่ไร้สถานะช่วยให้คุณควบคุมตำแหน่งและวิธีการใช้งานและแทนที่ / เยาะเย้ย / ฯลฯ เมื่อคุณต้องการ
การทำให้เป็นอินสแตนซ์ซิงเกิลตันช่วยให้มั่นใจได้ว่าคุณไม่ได้จัดสรรอ็อบเจ็กต์ประเภทใดมากเกินความจำเป็น (เนื่องจากคุณต้องการเพียงอย่างเดียว)
อันที่จริงฉันพบคำตอบอื่นที่ไม่ได้กล่าวถึงที่นี่: วิธีการแบบคงที่ทดสอบได้ยากกว่า
ดูเหมือนว่ากรอบการทดสอบส่วนใหญ่จะใช้งานได้ดีสำหรับการเยาะเย้ยวิธีการอินสแตนซ์ แต่ส่วนใหญ่ไม่ได้จัดการกับวิธีการจำลองแบบคงที่
ในชั้นเรียนภาษาโปรแกรมส่วนใหญ่จะหลีกเลี่ยงระบบประเภทต่างๆมากมาย ในขณะที่คลาสที่มีเมธอดแบบคงที่และตัวแปรเป็นอ็อบเจ็กต์ แต่บ่อยครั้งที่ไม่สามารถใช้อินเทอร์เฟซหรือขยายคลาสอื่น ๆ ได้ ด้วยเหตุนี้จึงไม่สามารถใช้ในลักษณะที่หลากหลายได้เนื่องจากไม่สามารถเป็นชนิดย่อยของประเภทอื่นได้ ตัวอย่างเช่นหากคุณมีอินเทอร์เฟซIFooable
ซึ่งจำเป็นต้องใช้โดยลายเซ็นหลายวิธีของคลาสอื่นStaticFoo
ไม่สามารถใช้อ็อบเจ็กต์คลาสแทนได้ในIFooable
ขณะที่FooSingleton.getInstance()
สามารถ (สมมติว่าFooSingleton
ใช้IFooable
)
โปรดทราบว่าขณะที่ฉันแสดงความคิดเห็นเกี่ยวกับคำตอบของ Heinzi ซิงเกิลตันเป็นรูปแบบในการควบคุมการสร้างอินสแตนซ์ แทนที่new Class()
ด้วยClass.getInstance()
ซึ่งทำให้ผู้เขียนClass
สามารถควบคุมอินสแตนซ์ได้มากขึ้นซึ่งเขาสามารถใช้เพื่อป้องกันการสร้างอินสแตนซ์ที่ไม่จำเป็น ซิงเกิลตันเป็นเพียงกรณีพิเศษของรูปแบบโรงงานและควรได้รับการปฏิบัติเช่นนี้ การใช้งานทั่วไปทำให้เป็นกรณีพิเศษของการลงทะเบียนทั่วโลกซึ่งมักจะลงเอยด้วยความไม่ดีเนื่องจากไม่ควรใช้การลงทะเบียนทั่วโลกเพียงแค่ตั้งใจ
หากคุณวางแผนที่จะให้ฟังก์ชั่นตัวช่วยระดับโลกวิธีการแบบคงที่ก็ใช้ได้ดี คลาสจะไม่ทำหน้าที่เป็นคลาส แต่เป็นเพียงเนมสเปซ ฉันขอแนะนำให้คุณรักษาความสัมพันธ์ที่ดีไม่เช่นนั้นคุณอาจพบปัญหาการมีเพศสัมพันธ์ที่แปลกประหลาด
Greetz
back2dos
มีการแลกเปลี่ยนระหว่างการใช้อันไหน Singletons อาจมีหรือไม่มีสถานะและอ้างถึงวัตถุ หากไม่ได้รักษาสถานะและใช้สำหรับการเข้าถึงทั่วโลกเท่านั้นแบบคงที่จะดีกว่าเนื่องจากวิธีการเหล่านี้จะเร็วขึ้น แต่ถ้าคุณต้องการใช้ประโยชน์จากวัตถุและแนวคิด OOP (ความหลากหลายทางมรดก) แล้วซิงเกิลตันจะดีกว่า
ลองพิจารณาตัวอย่าง: java.lang.Runtime เป็นคลาส singleton ใน java คลาสนี้อนุญาตให้นำไปใช้งานที่แตกต่างกันสำหรับแต่ละ JVM การใช้งานเป็นแบบเดี่ยวต่อ JVM หากคลาสนี้เป็นแบบคงที่เราจะไม่สามารถส่งผ่านการใช้งานที่แตกต่างกันตาม JVM
ฉันพบว่าลิงค์นี้มีประโยชน์จริงๆ: http://javarevisited.blogspot.com/2013/03/difference-between-singleton-pattern-vs-static-class-java.html ?
หวังว่าจะช่วย !!
สำหรับฉัน"ต้องการสถานะวัตถุใช้ Singleton ต้องการฟังก์ชันใช้วิธีคงที่"
มันขึ้นอยู่กับสิ่งที่คุณต้องการ เมื่อใดก็ตามที่คุณต้องการสถานะของวัตถุ (เช่นความหลากหลายเช่นสถานะ Null แทนnull
หรือสถานะเริ่มต้น) singleton เป็นตัวเลือกที่เหมาะสมสำหรับคุณในขณะที่วิธีการแบบคงที่จะใช้เมื่อคุณต้องการฟังก์ชัน (รับอินพุตแล้วส่งคืนเอาต์พุต)
ฉันแนะนำสำหรับกรณีซิงเกิลตันควรเป็นสถานะเดียวกันเสมอหลังจากสร้างอินสแตนซ์แล้ว ไม่ควรโคลนนิ่งหรือรับค่าใด ๆ เพื่อตั้งค่า (ยกเว้นการกำหนดค่าคงที่จากไฟล์เช่นไฟล์คุณสมบัติใน java)
ปล. ประสิทธิภาพระหว่าง 2 ตัวนี้ต่างกันเป็นมิลลิวินาทีดังนั้นควรเน้นที่สถาปัตยกรรมก่อน
Singleton ไม่ได้เป็นคนไร้สัญชาติ แต่ถือเป็นรัฐระดับโลก
เหตุผลบางประการที่ฉันคิดได้ในการใช้ Singleton ได้แก่ :