ตัวระบุตำแหน่งบริการเป็นเพียงความชั่วร้ายน้อยกว่าสองประการที่ต้องพูด "น้อยกว่า" เดือดถึงความแตกต่างทั้งสี่นี้ ( อย่างน้อยตอนนี้ฉันก็นึกไม่ออก ):
หลักการความรับผิดชอบเดียว
Service Container ไม่ละเมิดหลักการความรับผิดชอบเดียวเหมือนที่ Singleton ทำ Singletons ผสมผสานการสร้างอ็อบเจ็กต์และตรรกะทางธุรกิจในขณะที่ Service Container มีหน้าที่รับผิดชอบอย่างเคร่งครัดในการจัดการวงจรชีวิตอ็อบเจ็กต์ของแอปพลิเคชันของคุณ ในเรื่องนี้ Service Container ดีกว่า
ข้อต่อ
โดยปกติ Singletons จะถูกเข้ารหัสในแอปพลิเคชันของคุณเนื่องจากมีการเรียกวิธีการแบบคงที่ซึ่งนำไปสู่การเชื่อมโยงที่แน่นหนาและยากที่จะเยาะเย้ยการอ้างอิงในโค้ดของคุณ ในทางกลับกัน SL เป็นเพียงคลาสเดียวและสามารถฉีดได้ ดังนั้นในขณะที่คลาสทั้งหมดของคุณจะขึ้นอยู่กับมันอย่างน้อยก็เป็นการพึ่งพาคู่กัน ดังนั้นถ้าคุณไม่ติดตั้ง ServiceLocator เป็น Singleton นั้นค่อนข้างดีกว่าและทดสอบได้ง่ายกว่าด้วย
อย่างไรก็ตามคลาสทั้งหมดที่ใช้ ServiceLocator จะขึ้นอยู่กับ ServiceLocator ซึ่งเป็นรูปแบบหนึ่งของการมีเพศสัมพันธ์ด้วย สิ่งนี้สามารถบรรเทาได้โดยใช้อินเทอร์เฟซสำหรับ ServiceLocator ดังนั้นคุณจึงไม่ผูกพันกับการใช้งาน ServiceLocator ที่เป็นรูปธรรม แต่คลาสของคุณจะขึ้นอยู่กับการมีอยู่ของ Locator บางประเภทในขณะที่การไม่ใช้ ServiceLocator แต่อย่างใดจะเพิ่มการใช้ซ้ำได้อย่างมาก
การพึ่งพาที่ซ่อนอยู่
ปัญหาของการซ่อนการอ้างอิงมีอยู่อย่างมาก เมื่อคุณฉีดตัวระบุตำแหน่งไปยังชั้นเรียนที่คุณบริโภคคุณจะไม่ทราบการอ้างอิงใด ๆ แต่ในทางตรงกันข้ามกับ Singleton SL มักจะสร้างอินสแตนซ์การอ้างอิงทั้งหมดที่จำเป็นในเบื้องหลัง ดังนั้นเมื่อคุณเรียกใช้บริการคุณจะไม่ต้องลงเอยเหมือนMisko Hevery ในตัวอย่าง CreditCardเช่นคุณไม่จำเป็นต้องสร้างอินสแตนซ์การอ้างอิงทั้งหมดของการอ้างอิงด้วยมือ
การดึงการอ้างอิงจากภายในอินสแตนซ์ยังเป็นการละเมิดLaw of Demeterซึ่งระบุว่าคุณไม่ควรเจาะลึกถึงผู้ทำงานร่วมกัน อินสแตนซ์ควรพูดคุยกับผู้ทำงานร่วมกันในทันทีเท่านั้น นี่เป็นปัญหากับทั้ง Singleton และ ServiceLocator
รัฐสากล
ปัญหาของ Global State ก็บรรเทาลงได้เช่นกันเนื่องจากเมื่อคุณสร้างอินสแตนซ์ตัวระบุตำแหน่งบริการใหม่ระหว่างการทดสอบอินสแตนซ์ที่สร้างไว้ก่อนหน้านี้ทั้งหมดจะถูกลบเช่นกัน (เว้นแต่คุณจะทำผิดพลาดและบันทึกไว้ในแอตทริบิวต์แบบคงที่ใน SL) แน่นอนว่านั่นไม่ได้เป็นจริงสำหรับสถานะทั่วโลกในคลาสที่จัดการโดย SL แน่นอน
นอกจากนี้โปรดดู Fowler เกี่ยวกับService Locator vs Dependency Injectionเพื่อการสนทนาในเชิงลึกมากขึ้น
หมายเหตุเกี่ยวกับการอัปเดตของคุณและบทความที่เชื่อมโยงโดยSebastian Bergmann เกี่ยวกับโค้ดการทดสอบที่ใช้ Singletons : Sebastian ไม่ได้แนะนำว่าวิธีแก้ปัญหาที่เสนอทำให้การใช้ Singleons น้อยลงไม่มีปัญหา เป็นเพียงวิธีหนึ่งในการสร้างโค้ดที่มิฉะนั้นจะเป็นไปไม่ได้ที่จะทดสอบเพิ่มเติม แต่ก็ยังเป็นรหัสที่มีปัญหา ในความเป็นจริงเขาตั้งข้อสังเกตอย่างชัดเจนว่า: "Just Because You Can, Does not mean you should"