กรุณาขายตู้คอนเทนเนอร์ IoC ให้ฉันด้วย


17

ฉันเห็นหลายแนะนำให้ใช้คอนเทนเนอร์ IoC ในรหัส แรงจูงใจนั้นง่าย ใช้รหัสฉีดพึ่งพาต่อไปนี้:

class UnitUnderTest
{
    std::auto_ptr<Dependency> d_;
public:
    UnitUnderTest(
        std::auto_ptr<Dependency> d = std::auto_ptr<Dependency>(new ConcreteDependency)
    ) : d_(d)
    {
    }
};


TEST(UnitUnderTest, Example)
{
    std::auto_ptr<Dependency> dep(new MockDependency);
    UnitUnderTest uut(dep);
    //Test here
}

เป็น:

class UnitUnderTest
{
    std::auto_ptr<Dependency> d_;
public:
    UnitUnderTest()
    {
        d_.reset(static_cast<Dependency *>(IocContainer::Get("Dependency")));
    }
};


TEST(UnitUnderTest, Example)
{
    UnitUnderTest uut;
    //Test here
}

//Config for IOC container normally
<Dependency>ConcreteDependency</Dependency>

//Config for IOC container for testing
<Dependency>MockDependency</Dependency>

(ตัวอย่างข้างต้นเป็นตัวอย่างของซีพลัสพลัสสมมุติฐาน)

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

ดังนั้น .. มีประโยชน์อื่น ๆ อีกไหมในการใช้ภาชนะประเภทนี้หรือฉันแค่ไม่เห็นด้วยกับภาชนะที่แนะนำ?


1
โค้ดตัวอย่างดูเหมือนว่าเป็นตัวอย่างที่แย่มากของการใช้ IoC ฉันคุ้นเคยกับ C # เท่านั้น แต่แน่นอนว่ามีวิธีในการฉีดคอนสตรัคเตอร์และการตั้งค่าทางโปรแกรมใน C ++ ด้วยหรือไม่
rmac

คำตอบ:


12

ในแอพพลิเคชั่นขนาดใหญ่ที่มีเลเยอร์จำนวนมากและชิ้นส่วนที่เคลื่อนไหวจำนวนมากมันเป็นข้อเสียเปรียบที่เริ่มดูเล็กน้อยเมื่อเทียบกับข้อดี

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

มีภาชนะประเภทต่าง ๆ เช่นกัน ไม่ใช่ทั้งหมดที่พิมพ์อย่างเข้มงวดและไม่ใช่ทั้งหมดที่ต้องการไฟล์กำหนดค่า


3
แต่เป็นโครงการขนาดใหญ่ทำให้ปัญหาที่ผมกล่าวมาแล้วแย่ลง หากโครงการมีขนาดใหญ่ไฟล์กำหนดค่าจะกลายเป็นแม่เหล็กขนาดใหญ่ที่พึ่งพาตัวเองและมันจะง่ายยิ่งขึ้นถ้ามีการพิมพ์ผิดหนึ่งครั้งที่นำไปสู่พฤติกรรมที่ไม่ได้กำหนดในรันไทม์ (เช่นมีการพิมพ์ผิดในไฟล์ปรับแต่งจะทำให้การส่งข้อความนั้นทำให้เกิดพฤติกรรมที่ไม่ได้กำหนดหากได้รับคืนชนิดที่ไม่ถูกต้อง) สำหรับการขึ้นต่อกันของการพึ่งพาสิ่งเหล่านี้ไม่สำคัญ คอนสตรัคเตอร์จะดูแลการสร้างหรือการทดสอบจะเป็นการเยาะเย้ยการพึ่งพาระดับบนสุด
Billy ONeal

... ดำเนินการต่อ ... เมื่อโปรแกรมไม่ได้ถูกทดสอบการอ้างอิงที่เป็นรูปธรรมเริ่มต้นจะได้รับอินสแตนซ์ในแต่ละขั้นตอน คอนเทนเนอร์ชนิดอื่น ๆ คุณมีตัวอย่างบ้างไหม?
Billy ONeal

4
TBH ฉันไม่มีประสบการณ์มากมายเกี่ยวกับ DI implementations แต่ลองดูที่ MEF บน. NET ซึ่งสามารถทำได้ แต่ไม่ต้องพิมพ์อย่างเข้มงวดไม่มีไฟล์ config และการใช้งานอินเทอร์เฟซนั้น "ลงทะเบียนแล้ว" ในชั้นเรียนของตัวเอง BTW เมื่อคุณพูดว่า: "ผู้สร้างจะดูแลให้พวกเขาทำ" - ถ้านั่นคือสิ่งที่คุณกำลังทำอยู่ (หรือที่รู้จักว่า "การสร้างคอนสตรัคเตอร์ของชายผู้น่าสงสาร") ดังนั้นคุณไม่จำเป็นต้องใช้ภาชนะ ข้อได้เปรียบของคอนเทนเนอร์เหนือการทำนั่นคือคอนเทนเนอร์รวมศูนย์ข้อมูลเกี่ยวกับการอ้างอิงเหล่านั้นทั้งหมด
nlawalker

+1 สำหรับที่ความคิดเห็นล่าสุด - ประโยคสุดท้ายมีคำตอบ :)
บิลลี่ ONeal

1
คำตอบที่ดีที่ช่วยให้ฉันคร่ำครวญประเด็นทั้งหมด จุดนี้ไม่เพียงทำให้หม้อไอน้ำเรียบง่ายขึ้น แต่ยังช่วยให้องค์ประกอบที่อยู่ด้านบนของห่วงโซ่การพึ่งพาเป็นเพียงองค์ประกอบที่อยู่ด้านล่าง
Christopher Berman

4

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

ฉันเชื่อว่า Guice เป็น Java IoC framework ซึ่งในที่สุดก็มีการตั้งค่าที่ถูกต้อง


มีตัวอย่างที่คล้ายกันสำหรับ C ++ หรือไม่
Billy ONeal

@Billy ฉันไม่คุ้นเคยกับ C ++ ที่จะพูดได้

0

คำตอบ SOที่ยอดเยี่ยมนี้โดยBen Scheirman ให้รายละเอียดตัวอย่างโค้ดใน C #; ข้อดีของ IoC container (DI)

  • ห่วงโซ่การพึ่งพาของคุณสามารถกลายเป็นซ้อนกันได้
  • ช่วยให้สามารถใช้การเขียนโปรแกรมเชิงลักษณะ
  • การทำธุรกรรมฐานข้อมูลการประกาศ & ซ้อน
  • หน่วยงานประกาศ & ซ้อน
  • เข้าสู่ระบบ
  • เงื่อนไขก่อน / โพสต์ (ออกแบบตามสัญญา)

1
ฉันไม่เห็นว่าสิ่งเหล่านี้ไม่สามารถใช้งานได้ด้วยการสร้างคอนสตรัคเตอร์ที่เรียบง่าย
Billy ONeal

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