ฉีดพึ่งพาและ Singleton พวกเขาทั้งสองแนวคิดที่แตกต่างกันอย่างสิ้นเชิง?


17

ฉันเคยได้ยินเกี่ยวกับการใช้การฉีดขึ้นเหนือ Singleton สำหรับเพื่อนร่วมงานของฉัน ฉันยังไม่สามารถบอกได้ว่ามันเป็นสองรูปแบบมุมฉากซึ่งสามารถแทนที่ด้วยอีกรูปแบบหนึ่งได้หรือไม่? หรือ DI เป็นวิธีที่ทำให้รูปแบบซิงเกิลทดสอบได้หรือไม่?

โปรดดูข้อมูลโค้ดต่อไปนี้

    IMathFace obj = Singleton.Instance;

    SingletonConsumer singConsumer = new SingletonConsumer(obj);

    singConsumer.ConsumerAdd(10,20);

ยอมรับพารามิเตอร์ของชนิดSingletonConsumer IMathFaceแทนที่จะเข้าถึงคลาส singleton ภายในSingletonConsumerจะได้รับอินสแตนซ์ singleton ที่ส่งโดยผู้เรียก นี่เป็นตัวอย่างที่ดีของการบริโภคคลาสซิงเกิลผ่านการฉีดแบบพึ่งพาหรือไม่


คุณช่วยบอกฉันทีว่า DI สามารถเปลี่ยนซิงเกิลตันได้อย่างไร

7
Singleton เป็นรูปแบบการออกแบบ DI / IoC เป็นเทคนิค
เดฟ

2
DI ไม่สามารถแทนที่ Singleton มากกว่ากล้วยที่สามารถแทนที่คาร์บูเรเตอร์ มันเป็นแนวคิดที่แตกต่างอย่างสิ้นเชิง
เดฟ

ดังนั้นตัวอย่างของฉันถูกต้อง

1
ใช่ แต่อาจเกิดค่าใช้จ่ายในการห่อหุ้ม (ซึ่งเป็นจริงสำหรับผู้ที่ไม่ใช่ซิงเกิล) ดู: stackoverflow.com/questions/1005473//

คำตอบ:


17

MySingleton.Instanceผมคิดว่าเขาหมายความว่าคุณควรใช้ฉีดพึ่งพาการฉีดเช่นเดียวของบริการแทนการใช้การดำเนินโทนคลาสสิกที่มีการเข้าถึงแบบคงที่

public class MySingleton
{
    public static MySingleton Instance{get{...}};
}

ด้วยการใช้งานแบบซิงเกิลตันรหัสของคุณทั้งหมดขึ้นอยู่กับการบริการแบบซิงเกิล คุณพื้น hardcode MySingleton.Instanceสมมติฐานที่ว่าเป็นรหัสบริโภคเมื่อใดก็ตามที่คุณใช้

ในทางตรงกันข้ามกับ DI คุณจะได้รับอินสแตนซ์ของบริการที่ส่งผ่านไปยังตัวสร้างของคุณและเก็บไว้ ว่ามีเพียงอินสแตนซ์เดียวของบริการนี้คือรายละเอียดการใช้งาน คุณสามารถเปลี่ยนได้อย่างง่ายดายเพื่อให้รหัสการบริโภคเป็นอีกตัวอย่างหนึ่ง ด้วยวิธีนี้คุณจะมีคลาส / อินเทอร์เฟซที่เกิดขึ้นที่จะถูกนำมาใช้โดยอินสแตนซ์เดียวแทนที่จะบังคับใช้ว่ามีเพียงอินสแตนซ์เดียวเท่านั้น

สิ่งนี้มีประโยชน์หากคุณต้องการใช้การจำลองการให้บริการสำหรับการทดสอบหรือหากส่วนต่าง ๆ ของโปรแกรมต้องการการกำหนดค่าที่แตกต่างกันของบริการนั้น


4

ใช่คุณถูก. แทนที่จะเข้าถึงวัตถุผ่านซิงเกิลคุณกำลังผ่านการอ้างอิงถึงมันดังนั้นคุณจึงใช้การสร้างคอนสตรัคชัน

สิ่งที่คนอื่นชี้ให้เห็นคือความคิดเหล่านี้ไม่เกี่ยวข้อง การใช้อินสแตนซ์ของซิงเกิลตันนั้นไม่มีอะไรพิเศษเพราะวัตถุที่คุณฉีดเข้าไปนั้นไม่ได้สนใจว่าวัตถุที่ถูกฉีดนั้นมาจากไหน


3

มีกรณีหนึ่งที่รูปแบบ Singleton และ DI / IoC ตัดกัน - การฉีด Singleton

เฟรมเวิร์ก DI ส่วนใหญ่สามารถกำหนดค่าให้อินสแตนซ์ของวัตถุที่ถูกฉีดอินสแตนซ์เดียวได้ วัตถุผู้บริโภคใด ๆ ที่ร้องขออินสแตนซ์ของวัตถุนั้นจะได้รับอินสแตนซ์เดียวกัน อินสแตนซ์นั้นโดยนิยามของซิงเกิล ที่เกี่ยวกับมันสำหรับการทับซ้อนกันในแนวคิด


2

ความสับสนในที่นี้คือแนวคิดสองข้อได้รับการรวมเข้าด้วยกัน: singleton และ static accessor / gateway ไปยังอินสแตนซ์ singleton

ตามที่คุณระบุไว้อย่างถูกต้องเพื่อนร่วมงานของคุณแนะนำว่าต้องพึ่งพาการฉีดมากกว่าเข้าถึงโดยตรงโดยใช้Singleton.Instance(เกตเวย์คงที่)

เหตุผลที่สิ่งนี้ไม่เกี่ยวข้องกับรูปแบบซิงเกิลจริงๆนั่นคือแนวคิด DI เดียวกันใช้กับการสร้างอินสแตนซ์ของวัตถุที่ไม่ใช่ซิงเกิลด้วยnew Foo()เช่นกัน การพึ่งพาจะถูกฉีดโดยไม่คำนึงว่ามันจะเป็นการดำเนินการเดี่ยว

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.