tgoop.com/javapro_ir/4567
Create:
Last Update:
Last Update:
📘 موضوع: Dependency Injection در جاوا — مفهوم و اهمیت آن در طراحی شیءگرا
در برنامهنویسی شیءگرا، کلاسها معمولاً برای انجام کارهای خود به اشیای دیگر نیاز دارند.
به این اشیای وابسته، Dependency (وابستگی) گفته میشود.
اما نحوهی ایجاد و مدیریت این وابستگیهاست که تفاوت بین کد ضعیف و کد قابلتوسعه و تستپذیر را مشخص میکند.
🔹 ۱. مشکل: وابستگی مستقیم بین کلاسها
فرض کنید کلاس Car برای کار کردن به یک Engine نیاز دارد 👇
class Engine {
void start() {
System.out.println("Engine started!");
}
}
class Car {
private Engine engine = new Engine(); // وابستگی مستقیم!
void drive() {
engine.start();
System.out.println("Car is moving!");
}
}
در نگاه اول ساده است، اما یک مشکل بزرگ دارد:
کلاس Car خودش تصمیم گرفته که چطور Engine را بسازد.
اگر روزی بخواهید نوع موتور را تغییر دهید (مثلاً از Engine به ElectricEngine)، باید کد Car را تغییر دهید ❌
یعنی Car به Engine وابسته شده و این برخلاف اصل Open/Closed Principle از SOLID است.
🔹 ۲. راهحل: تزریق وابستگی (Dependency Injection)
در روش Dependency Injection، به جای اینکه کلاس خودش وابستگی را بسازد،
ما آن را از بیرون تزریق میکنیم (از طریق سازنده، Setter یا Interface).
📘 مثال با Constructor Injection:
class Engine {
void start() {
System.out.println("Engine started!");
}
}
class Car {
private Engine engine;
// وابستگی از بیرون تزریق میشود
public Car(Engine engine) {
this.engine = engine;
}
void drive() {
engine.start();
System.out.println("Car is moving!");
}
}
public class Main {
public static void main(String[] args) {
Engine engine = new Engine();
Car car = new Car(engine); // تزریق وابستگی
car.drive();
}
}
در اینجا، Car دیگر مسئول ساخت Engine نیست — فقط از آن استفاده میکند.
در نتیجه میتوانیم نوع موتور را در آینده بهراحتی تغییر دهیم، بدون دست زدن به کد Car ✅
🔹 ۳. انواع Dependency Injection
1. Constructor Injection → تزریق از طریق سازنده (مثل مثال بالا)
2. Setter Injection → تزریق از طریق متد Setter
3. Interface Injection → وابستگی از طریق متدی در Interface تزریق میشود
📘 مثال Setter Injection:
class Car {
private Engine engine;
public void setEngine(Engine engine) {
this.engine = engine;
}
void drive() {
engine.start();
System.out.println("Car is moving!");
}
}
🔹 ۴. مزایای استفاده از Dependency Injection
✅ کاهش Coupling (وابستگی مستقیم) بین کلاسها
✅ افزایش Testability (قابل تست شدن راحتتر)
✅ افزایش Reusability (قابل استفاده مجدد بودن کلاسها)
✅ رعایت اصول SOLID مخصوصاً Open/Closed و Single Responsibility
📘 مثال تست راحتتر با DI:
class MockEngine extends Engine {
void start() {
System.out.println("Mock engine started (for testing)");
}
}
public class Test {
public static void main(String[] args) {
Car car = new Car(new MockEngine());
car.drive(); // تست بدون اجرای موتور واقعی
}
}
در اینجا، بدون تغییر در کلاس Car`، یک `MockEngine تزریق کردیم تا تست انجام شود.
🔹 ۵. Dependency Injection در فریمورکها (مثل Spring)
فریمورکهایی مانند Spring این فرایند را بهصورت خودکار انجام میدهند.
یعنی فقط با استفاده از Annotationهایی مانند @Component و `@Autowired`،
Spring خودش وابستگیها را میسازد و تزریق میکند.
📘 مثال:
@Component
class Engine {
void start() {
System.out.println("Engine started!");
}
}
@Component
class Car {
private final Engine engine;
@Autowired
public Car(Engine engine) {
this.engine = engine;
}
void drive() {
engine.start();
System.out.println("Car is moving!");
}
}
در این حالت، Spring Container خودش متوجه میشود که Car به Engine نیاز دارد و آن را تزریق میکند.
BY برنامه نویسی جاوا | Java
Share with your friend now:
tgoop.com/javapro_ir/4567