ฉันได้อ่านความคิดเห็นที่แตกต่างกันเกี่ยวกับรูปแบบซิงเกิล บางคนยืนยันว่าควรหลีกเลี่ยงค่าใช้จ่ายและอื่น ๆ ที่สามารถเป็นประโยชน์ในบางสถานการณ์
สถานการณ์หนึ่งที่ฉันใช้ singletons คือเมื่อฉันต้องการโรงงาน (สมมติว่าวัตถุประเภท f) เพื่อสร้างวัตถุของคลาส A แน่นอนโรงงานถูกสร้างขึ้นครั้งเดียวโดยใช้พารามิเตอร์การกำหนดค่าบางอย่างจากนั้นจะใช้แต่ละครั้งที่วัตถุของ พิมพ์ A ถูกสร้างขึ้น ดังนั้นทุกส่วนของรหัสที่ต้องการอินสแตนซ์ A ดึงค่าซิงเกิลตันและสร้างอินสแตนซ์ใหม่เช่น
F& f = F::instance();
boost::shared_ptr<A> a = f.createA();
ดังนั้นสถานการณ์ทั่วไปของฉันก็คือ
- ฉันต้องการอินสแตนซ์เดียวของคลาสอย่างใดอย่างหนึ่งด้วยเหตุผลการปรับให้เหมาะสม (ฉันไม่ต้องการวัตถุหลายโรงงาน) หรือสำหรับการแบ่งปันสถานะทั่วไป (เช่นโรงงานทราบจำนวนอินสแตนซ์ของ A ที่ยังคงสามารถสร้างได้)
- ฉันต้องการวิธีการเข้าถึง f ของอินสแตนซ์นี้ในสถานที่ต่าง ๆ ของรหัส
ฉันไม่สนใจในการอภิปรายว่ารูปแบบนี้ดีหรือไม่ดี แต่สมมติว่าฉันต้องการหลีกเลี่ยงการใช้ซิงเกิลตันฉันสามารถใช้รูปแบบอื่นแบบใดได้บ้าง
แนวคิดที่ฉันมีคือ (1) นำวัตถุของโรงงานออกจากรีจิสตรีหรือ (2) เพื่อสร้างโรงงานในบางช่วงระหว่างการเริ่มต้นโปรแกรมแล้วส่งโรงงานเป็นพารามิเตอร์
ในโซลูชัน (1) ตัวรีจิสตรีนั้นเป็นซิงเกิลดังนั้นฉันเพิ่งเปลี่ยนปัญหาการไม่ใช้ซิงเกิลตันจากโรงงานไปยังรีจิสตรี
ในกรณี (2) ฉันต้องการบางแหล่งเริ่มต้น (วัตถุ) จากที่วัตถุโรงงานมาดังนั้นฉันกลัวว่าฉันจะถอยกลับไปยังซิงเกิลอื่นอีกครั้ง (วัตถุที่ให้อินสแตนซ์จากโรงงานของฉัน) โดยการติดตามห่วงโซ่ของซิงเกิลนี้กลับฉันสามารถลดปัญหาให้เหลือหนึ่งซิงเกิล (ทั้งแอปพลิเคชัน) โดยที่ซิงเกิลตันอื่นทั้งหมด ได้รับการจัดการโดยตรงหรือโดยอ้อม
ตัวเลือกสุดท้ายนี้ (ใช้ซิงเกิลตันเริ่มต้นหนึ่งตัวที่สร้างวัตถุที่ไม่ซ้ำกันอื่น ๆ ทั้งหมดและอัดฉีดซิงเกิลอื่นทั้งหมดในตำแหน่งที่ถูกต้อง) เป็นวิธีแก้ปัญหาที่ยอมรับหรือไม่? นี่เป็นวิธีแก้ปัญหาที่แนะนำโดยปริยายเมื่อมีคำแนะนำว่าไม่ควรใช้ซิงเกิลตันหรือมีคำตอบอื่นใดอีกเช่นในตัวอย่างที่แสดงด้านบน
แก้ไข
เนื่องจากฉันคิดว่าประเด็นคำถามของฉันถูกเข้าใจผิดโดยบางคนนี่เป็นข้อมูลเพิ่มเติม ตามที่อธิบายไว้ที่นี่คำว่า ซิงเกิลสามารถระบุ (a) คลาสที่มีวัตถุอินสแตนซ์เดียวและ (b) รูปแบบการออกแบบที่ใช้ในการสร้างและเข้าถึงวัตถุดังกล่าว
เพื่อให้สิ่งต่าง ๆ ชัดเจนขึ้นให้เราใช้คำเฉพาะสำหรับ (a) และ รูปแบบซิงเกิลสำหรับ (b) ดังนั้นฉันจึงรู้ว่ารูปแบบซิงเกิลและการฉีดขึ้นต่อกันคืออะไร (BTW เมื่อเร็ว ๆ นี้ฉันใช้ DI หนักเพื่อลบอินสแตนซ์ของรูปแบบซิงเกิลออกจากโค้ดที่ฉันใช้งานอยู่)
จุดของฉันคือว่าถ้ากราฟวัตถุทั้งหมดถูกสร้างอินสแตนซ์จากวัตถุเดียวที่อาศัยอยู่บนสแต็กของวิธีการหลักจะมีความจำเป็นในการเข้าถึงวัตถุที่ไม่ซ้ำกันบางอย่างผ่านรูปแบบซิงเกิล
คำถามของฉันคือการมีการสร้างกราฟวัตถุที่สมบูรณ์และการเดินสายขึ้นอยู่กับวิธีการหลัก (เช่นผ่านกรอบ DI ที่ทรงพลังบางอย่างที่ไม่ได้ใช้รูปแบบตัวเอง) เป็นโซลูชั่นฟรีรูปแบบซิงเกิลเดียว