Spring Boot : Dependency Injection (DI) Chìa khoá để code xịn và dễ bảo trì
Khi mới bắt đầu học lập trình hướng đối tượng hoặc các framework như Spring Boot, thuật ngữ Dependency Injection (DI) chắc chắn sẽ làm ta bối rối.Nghe có vẻ "đao to búa lớn", nhưng thực chất ý tưởng cốt lỗi ko qua căng thẳng đâu bro
Bài viết này, anh em mình cùng tìm hiểu về DI nhé, tại sao chúng ta phải cần nó và cách áp dụng nó trong Java/Spring Boot

1.Đặt vấn đề
Tưởng tượng Class PC của bạn cần một Card đồ hoạ (GPU) để xử lý tác vụ. Theo cách viết code "nông dân" và cứng nhắc thif sẽ làm như sau
// Ví dụ A: Code không dùng DI
public class PC {
// Tự khởi tạo và hàn chết Card Nvidia vào bên trong
private NvidiaGPU gpu = new NvidiaGPU();
public void xuLyTacVu() {
System.out.print("Đang chạy PC với: ");
gpu.render();
}
}
🚨 Vấn đề ở đây là gì ????
- PC bị gắn chặt với NvidiaGPU
- Nếu bạn muốn nâng cấp lên linh kiện khác (AMD_GPU) thì bạn buộc phải mở class PC ra và sửa code
- Khi viết Unit Test cho PC, bạn không thể nào cô lập nó, vì nó luôn gắn chặt với NvidiaGPU thật
2. Giải pháp: Dependency Injection (DI)
Trong thực tế, khi ta mua một cái case PC có khe cắm. Cái case chỉ quan tâm có thứ gì đó cắm vào khe cắm đó, không quan tâm nó là hãng nào
DI chính la thiết kế code với các khe cắm (thông qua interface) và nhận linh kiện từ bên ngoài (thông qua Constructor)
2.1 Thiết lập "khe cắm" và "linh kiện"
Bước 1: Chuẩn hoá khe cắm (interface)
public interface GPU {
void render();
}
Bước 2: Các linh kiện tuân thủ (implementations)
public class NvidiaGPU implements GPU {
@Override
public void render() { /* ... code Nvidia ... */ }
}
public class AMDGPU implements GPU {
@Override
public void render() { /* ... code AMD ... */ }
}
2.2 Cơ chế "lắp ghép" (Constuctor Injection) Class PC giờ đây chỉ đơn giản là một cái case rỗng, sẵn sàng nhận linh kiện
// Ví dụ B: Code dùng DI (Constructor Injection)
public class PC {
// PC chỉ cần biết nó cần một thứ thuộc loại GPU
private final GPU gpu;
// Constructor: Đây là "khe cắm" nhận linh kiện từ bên ngoài đưa vào
public PC(GPU cardDoHoa) {
this.gpu = cardDoHoa;
}
public void xuLyTacVu() {
System.out.print("Đang chạy PC với: ");
gpu.render();
}
}
Định nghĩa đơn giản : Dependency Injection là kỹ thuật mà các đối tượng cần thiết được truyền vào class thay vì class tự khởi tạo chúng
3. Tại sao chúng ta cần DI ??
DI không chỉ là một phong cách code mà nó là chìa khoá mở ra tính năng thiết kế cấp
-
Loose Coupling (Liên kết lỏng) : Các clas độc lập, không biết mặt nhau. Class PC không quan tâm GPU là ai chỉ cần nó làm được việc. Điều này giúp code dễ bảo trì và mở rộng hơn
-
Dễ dàng test : Đây là lợi ích lớn nhất. Khi test PC, bạn có thể tiêm vào đó một GPU_giả để kiểm tra PC có chạy đúng logic của nó hay không, mà không cần bặt cả hệ thống card đồ hoạ thật lên.Giống như bạn đưa đầu bếp "nguyên liệu giải" để test quy trình nấu ăn ấy
-
Dễ dàng thay đổi/ nâng cấp : giống như đổi từ NvidiaGPU sang AMDGPU ấy , bạn chỉ cần đổi tên Bean được khởi tạo ở dile cấu hình không cần sửa logic code trong class PC
KẾT LUẬN
Dependency Injection là một kỹ thuật thiết kế đơn gainr nhưng cực kỳ hữu ích, giúp chúng ta chuyển từ tư duy "cố định hàn chặt"->"lắp ghép module". Khi bạn làm việc với Spring Boot, bạn đang sử dụng DI mỗi ngày mà không hay biết
Hãy nhớ: càng ít phụ thuộc chặt chẽ , ứng dụng càng linh hoạt và bảo trì
All rights reserved