Dependency Injection (DI )

Dependency Injection คือรูปแบบการเขียนโปรแกรม ที่ช่วยให้ Code ของเรามีความยืดหยุ่น และทดสอบได้ง่ายขึ้น โดยลดการยึดติดกันของ Object


แนวคิดพื้นฐาน: “เลิกสร้างเอง แต่รอรับจากภายนอก”

โดยปกติเวลา Class หนึ่งต้องการใช้งานอีก Class หนึ่ง เรามักจะเขียนคำสั่ง new ขึ้นมาในตัว Class นั้นเลย แต่ DI บอกว่า “อย่าสร้างเอง” ให้รอรับ Object นั้นผ่านทาง Constructor หรือ Method แทน

เปรียบเทียบให้เห็นภาพ

  • แบบเดิม: คุณอยากกินกาแฟ คุณต้องไปปลูกต้นกาแฟ คั่วเมล็ด และชงเอง
  • แบบ DI: คุณแค่บอกว่า “ต้องการกาแฟ” แล้วมีพนักงานยกมาเสิร์ฟให้ คุณมีหน้าที่แค่ดื่ม

ทำไมเราถึงต้องใช้ Dependency Injection ?

  1. Loose Coupling: Class ต่าง ๆ ไม่ยึดติดกันแน่นจนเกินไป ทำให้การแก้ไข Code ในส่วนหนึ่งไม่กระทบกับส่วนอื่นโดยไม่จำเป็น
  2. Easier Testing: เราสามารถส่ง “Object จำลอง” เข้าไปแทนที่ Object จริงในขณะทดสอบได้ เช่น แทนที่จะต่อ Database จริง เราก็ส่ง Database จำลองเข้าไปแทน
  3. Maintainability: เมื่อต้องการเปลี่ยน Implementation เราแค่เปลี่ยนที่จุดฉีด จุดเดียว ไม่ต้องไล่แก้ทุก Class

ประเภทของ Dependency Injection

การฉีด Dependency เข้าไปใน Class หลัก ๆ มี 3 วิธี

  • Constructor Injection: ส่ง Dependency ผ่านทาง Constructor
  • Setter Injection: ส่ง Dependency ผ่านทาง Setter Method หลังจากสร้าง Object แล้ว
  • Interface Injection: ตัว Dependency จะมี Interface กำหนดไว้เพื่อให้ Injector ส่งข้อมูลมาให้

ตัวอย่าง Code


แบบที่ไม่ได้ใช้ DI

แบบนี้ Car จะยึดติดกับ GasEngine เสมอ ถ้าอยากเปลี่ยนเป็น ElectricEngine ต้องรื้อ Code ใหม่

public class Car { private GasEngine engine; public Car () { this.engine = new GasEngine () ; // สร้างเองภายใน ยึดติดแน่น }
}

แบบที่ใช้ DI

แบบนี้ Car รับอะไรก็ได้ที่เป็น IEngine ทำให้เราเปลี่ยนประเภทเครื่องยนต์ได้โดยไม่ต้องแก้ Code ใน Class Car

public class Car { private IEngine _engine; // รับเครื่องยนต์จากภายนอก public Car (IEngine engine) { this._engine = engine; }
}

สรุป

Dependency Injection ไม่ได้เป็นเพียงเทคนิคการเขียนโปรแกรม แต่เป็นหัวใจสำคัญของการออกแบบ Software สมัยใหม่ที่เน้นความยืดหยุ่นและการจัดการระบบขนาดใหญ่ให้มีประสิทธิภาพครับ


อ่านเพิ่มเติม