การฉีดพึ่งพามือเป็นทางเลือกที่ดีกว่าในการจัดองค์ประกอบและความหลากหลาย?


13

ก่อนอื่นฉันเป็นโปรแกรมเมอร์ระดับต้น ในความเป็นจริงฉันกำลังจบระดับ AS ด้วยโปรเจ็กต์สุดท้ายของฤดูร้อน ในงานใหม่ของฉันเมื่อไม่มีโครงการให้ฉันทำ (พวกเขากำลังรอที่จะเติมทีมด้วยการจ้างงานใหม่) ฉันได้รับหนังสือให้อ่านและเรียนรู้จากในขณะที่ฉันรอ - ตำราบางเล่มอื่น ๆ ไม่มาก (เช่น Code Complete) หลังจากอ่านหนังสือเหล่านี้ฉันได้หันไปใช้อินเทอร์เน็ตเพื่อเรียนรู้ให้มากที่สุดและเริ่มเรียนรู้เกี่ยวกับ SOLID และ DI (เราได้พูดถึงหลักการทดแทนของ Liskov แต่ไม่ได้มีแนวคิด SOLID อื่น) เพื่อที่ฉันจะได้เรียนรู้ฉันนั่งลงเพื่อเรียนรู้ให้ดีขึ้นและเริ่มเขียนโค้ดเพื่อใช้ DI ด้วยมือ (ไม่มีกรอบ DI บนคอมพิวเตอร์การพัฒนา)

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

คำตอบ:


21

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

เฟรมเวิร์ก DI สร้างเฉพาะบนแนวคิดนี้เท่านั้นและ (บางส่วน) ทำให้ส่วนที่น่าเบื่อของการเชื่อมต่อออบเจ็กต์การเชื่อมต่อเข้าด้วยกันโดยอัตโนมัติ สิ่งนี้อาจต้องใช้รหัสจำนวนมากในโครงการขนาดใหญ่เมื่อดำเนินการด้วยมือ

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

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


1
Dependency Injection (DI) เป็นรูปแบบหนึ่งของการกลับคำของการควบคุม (IoC)
Matthew Flynn

@ MatthewFlynn แน่นอน สำหรับการอ้างอิง: martinfowler.com/articles/inject.html
PéterTörök

1
นั่นคือการอ้างอิงของฉัน เขาพูดถึงเกี่ยวกับ "ภาชนะบรรจุที่มีน้ำหนักเบา" ใหม่ซึ่งควบคุมการผกผันซึ่งเป็นสิ่งที่พบได้บ่อยในขณะที่ผู้ฟังเหตุการณ์ UI เป็นรูปแบบของ IoC เขาขนานนามวัตถุที่มีผลผูกพันว่า Spring และคอนเทนเนอร์ IoC อื่น ๆ ทำเช่น Dependency Injection เพื่อแยกความแตกต่างจาก Inversion of Control ในรูปแบบอื่น
Matthew Flynn

อ๊ะ - ฉันพลาด "แน่นอน" ฉันคิดว่าคุณขัดแย้งกับฉัน ... ขอโทษ
Matthew Flynn

ย่อหน้าสุดท้ายของคุณทำให้ฉันรู้สึกดีขึ้นเล็กน้อย ตลอดเวลาที่ฉันทำงานเกี่ยวกับโครงการเรียนรู้เล็ก ๆ น้อย ๆ ของฉันฉันพูดกับตัวเองอยู่เสมอว่า "นี่ให้ความรู้สึกเหมือนมีหลายรูปแบบ ... " แต่น่าเสียดายที่. Net และ c # ที่งานของฉันล้าสมัยอย่างน่ากลัว แต่จากการมองเข้าไป Unity ได้รวมตัวในกรอบ c # ที่คุณพูดถึงหรือไม่
Drake Clarris

22

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

"การพึ่งพาการฉีด" เป็นคำศัพท์ 25 ดอลลาร์สำหรับแนวคิด 5 เซ็นต์

นั่นคือจากโพสต์ของชอร์ซึ่งเคลียร์ทุกอย่างให้ฉัน ตัวอย่างเช่น:

ป.ร. ให้ไว้

class Engine {public abstract void start()}
class V8 extends Engine {...}
class V6 extends Engine {...}

แทนที่จะเขียน:

class Car
{
    private Engine engine;
    public Car()
    {
        this.engine = new V6();
    }

    public void start()
    {
        this.engine.start();
    }
}

คุณเขียนอะไรเช่นนี้:

class Car
{
    private Engine engine;
    public Car(Engine a)
    {
        this.engine = a;
    }

    public void start()
    {
        this.engine.start();
    }
}

...

Car F = new Car(new V8());

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

ตัวอย่างรถยนต์เฉพาะนี้ใช้ประเภทย่อยของ DI ที่เรียกว่า "Constructor Injection" ซึ่งหมายถึงว่าการพึ่งพาถูกมอบให้เป็นอาร์กิวเมนต์ตัวสร้าง คุณยังสามารถใช้setEngine(Engine a)วิธีสำหรับ "Setter Injection" และอื่น ๆ ได้ แต่ประเภทย่อยเหล่านี้ดูเหมือนจะหยาบคายกับฉัน

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

แค่นั้นแหละ.


0

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

  • ศูนย์กลางของการสร้างวัตถุ
  • จัดเตรียมซิงเกิลในแต่ละหัวข้อ
  • เทคนิคเชิงกว้างเช่นการสกัดกั้น

0

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

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