Search trên Google các bạn có thể tìm thấy hàng đống bài viết về cái chủ đề này, mỗi người một kiểu trình bày khác nhau. Có thể có bạn sẽ lĩnh hội rất nhanh, cũng có thể không nên mình xin tổng hợp lại và cố gắng viết lại nó theo một kiểu dễ hiểu nhất (sẽ cố gắng hết sức 😀 ).
Ý tưởng chính của Dependency Injection đó là bạn không phụ thuộc vào ai cả và người khác cũng không phụ thuộc vào bạn. Khi cần mình sẽ gọi bạn và bạn cũng vậy.
Để mình nói cụ thể hơn nhé!
Ngày xưa mình thường viết code như thế này:
Giả sử bạn có một đối tượng là Circle, đối tượng này có một phương thức là draw() như sau:
1 2 3 4 5 |
public class Circle { public void draw() { System.out.println("Drawing circle ..."); } } |
Giờ mình muốn sử dụng đối tượng này để vẽ hình tròn, mình sẽ khởi tạo đối tượng Circle ngay trong constructor và mình sẽ code như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
public class Drawing { public Circle circle; public Drawing() { circle = new Cirle(); } public void preparing() { System.out.println("Preparing ..."); } public void draw() { circle.draw(); } public static void main(String[] args) { Drawing drawing = new Drawing(); drawing.draw(); } } |
Rõ ràng bạn thấy đối tượng Drawing của mình đang phụ thuộc vào đối tượng Circle của bạn (nghĩa là mình đang phụ thuộc vào bạn đấy), bởi vì mỗi khi chạy ứng dụng, đối tượng Drawing lại phải giữ luôn thông tin của đối tượng Circle. Đây là nhược điểm thứ nhất của cách code này.
Nhược điểm thứ hai đó là nếu sau này mình muốn vẽ một tam giác, mình lại phải đi khai báo lại đối tượng khác để đáp ứng nhu cầu của mình. Đối tượng Drawing của mình vì thế cứ phải thay đổi liên tục theo nhu cầu.
Vậy giờ làm sao để giải quyết hai nhược điểm này?
Nhược điểm thứ hai chúng ta có thể giải quyết dễ dàng bằng cách sử dụng interface. Đối tượng Circle của bạn giờ sẽ hiện thực một interface tên là Shape, cụ thể như sau:
1 2 3 |
public interface Shape { public void draw(); } |
1 2 3 4 5 |
public class Circle implement Shape { public void draw() { System.out.println("Drawing circle ..."); } } |
Sau này mình muốn vẽ tam giác thì chỉ cần viết thêm một lớp mới và hiện thực interface Shape là được.
Đối với nhược điểm thứ nhất, Dependency Injection sinh ra để giải quyết nó.
Hãy xem Dependency Injection giải quyết như thế nào nhé, mình xin sửa lại đối tượng Drawing như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
public class Drawing { private Shape shape; public Drawing(Shape shape) { this.shape = shape; } public void setShape(Shape shape) { this.shape = shape; } public void preparing() { System.out.println("Preparing ..."); } public void draw() { shape.draw(); } } |
Các bạn thấy đó, nếu bây giờ mình chỉ muốn đối tượng Drawing của mình chỉ chuẩn bị các dụng cụ để vẽ mà thôi, mình sẽ không cần gọi đến đối tượng Circle của bạn, code sẽ như sau:
1 2 |
Drawing drawing = new Drawing(null); drawing.preparing(); |
Và giờ sau khi chuẩn bị xong, mình sẽ cần bạn để vẽ một hình tròn, mình sẽ gọi đến bạn:
1 2 3 4 5 6 |
Drawing drawing = new Drawing(null); drawing.preparing(); Shape shape = new Circle(); drawing.setShape(shape); drawing.draw(); |
Thật ra, những code này nhiều bạn đã làm rồi nhưng không biết nó là Dependency Injection thôi.
new_spring
Cảm ơn bạn, bài viết rất dễ hiểu.
quang
cám ơn bài viết dễ hiểu lắm bạn
Truongxp
Em thấy phần đầu bác vẽ 1 hình tròn tạo contructor và tạo hàm draw() dài, e nghĩ chỉ cần viết như thế này thôi ak:
public class Drawing {
public Cirle cirle = new Cirle();
public static void main(String[] args) {
Drawing drawing = new Drawing();
drawing.cirle.draw();
}
}
nvp
Cách của bạn ngắn gọn nhưng sau này chương trình phình ra muốn tái sử dụng mấy cái kia thì cũng phải viết hàm thôi bạn ơi.
Bí danh
Bài viết rất dễ hiểu. Cảm ơn anh nhiều :))))
VanVTT
Anh ơi, anh có thể làm một bài về Lock trong Hibernate và Lock trong transaction được không ạ?
Hoặc anh có thể cho em skype hay email gì của anh được không nhi? (plz)
Khanh Nguyen
Có form liên hệ đó em.
gaconbka
quá hay và dễ hiểu, hi vọng anh ra thêm nhiều bài viết mới về spring, thanks a lot 🙂
Trẻ Trâu
Tuy bài viết cũ rồi nhưng rất hay, quan trọng nhất là rất xúc tich dễ hiều, mình đã được khai sáng .
Thank bạn !
Khanh Nguyen
Thanks bạn!
new_bie
Hay quá anh ơi, em mới học spring mà đọc mãi không hiểu, may thấy bài này.
Thanks anh!
Nguyen
Mình đã xem khái niệm này ở 1 vài trang, đây là bài viết dễ hiểu nhất và hữa ích nhất đối với mình, cảm ơn bạn và hy vọng bạn sẽ có thêm nhiều bài viết hay trong tương lai
Vinh
Cảm ơn anh. Bài viết rất dễ hiểu ạ. =D