Tìm hiểu về Dependency injection trong Java

Dependency Injection (DI) là design pattern quan trọng trong Java. Trước đó, người ta gọi là Inversion of Control (IoC). DI là nền tảng đầu tiên, căn bản để xây dựng nên Spring Framework (được chống lưng bởi Pivotal), Guice (được chống lưng bởi Google) [1].

VÍ DỤ MINH HỌA DEPENDENCY INJECTION BỞI JAVA THUẦN

Các ví dụ sau đây dựa trên ví dụ minh hoạ của Phil Webb [2] trong khoá học Building Microservices with Spring Boot 2.0 (có đôi chút chỉnh sửa lại). Tạo class CreditCard.java , đó là thực thể (entity) thẻ tín dụng, gồm các thuộc tính

+ id: Số định danh
+ creditCardHolder: Họ và tên chủ thẻ tín dụng
+ creditCardNumber: Số thẻ tín dụng
+ ccv: 3 chữ số bảo mật, Nếu ban có 1 chiếc thẻ thanh toán quốc tế MasterCard hoặc VisaCard, bạn sẽ nhìn thấy 3 số này ở mặt sau (3 số này là bảo mật, nên giữ kín)

Tạo class Order, thể hiện thực thể (entity) đơn đặt hàng. Một đơn đặt hàng có các thuộc tính
+ id: Số định danh (mã) đơn hàng
+ amount: Số tiền/Giá trị đơn hàng (hoá đơn)
+ note: Ghi chú

Có class chứa phương thức để xử lý thanh toán, tác động vào tài khoản thẻ tín dụng của bạn dựa trên số thẻ và số tiền chi tiêu:

Có class để hiện thực hoá design pattern có tên Dependency Injection, có 2 phương thức phổ biến nhất để khai thác mô hình dependency injection là:

+ Dựa trên method constructor (*)
+ Dựa trên method setter

Ở đây chúng ta sử dụng (*) trong class OrderService

 

Như vậy, chúng ta làm 2 việc sau
+ khởi tạo một instance (object) của class OrderService
+ khởi tạo việc xử lý một đơn hàng và gọi đến phương thức thanh toán tác động đến thẻ tín dụng bằng phương thức placeOrder, (gọi được phương thức này sau khi khởi tạo instance (object) của class CreditCardProcessor)

bằng kỹ thuật Dependency Injection (tạm dịch là “Chèn phụ thuộc”).

VÍ DỤ MINH HOẠ DEPENDENCY BỞI SPRING FRAMEWORK

 

LỢI ÍCH CỦA DEPENDENCY INJECTION

+ Phân tách được sự phụ thuộc. Khi ứng dụng ở quy mô nhỏ, kiến trúc đơn giản vẫn được. Nhưng khi ứng dụng Java ở quy mô lớn (có hàng trăm, hàng nghìn class, sử dụng nhiều thư viện nội bộ và bên ngoài) gọi tham chiếu lẫn nhau, kiến trúc cần sự tinh tế/khoa học, đó là lúc nên nên dùng Dependency Injection.

+ Nhờ sự phân tách phụ thuộc (tham chiếu), dó đó ứng dụng Java có thể viết unit test (JUnit test, TestNG, v.v..) dễ dàng.

+ Nhờ có sự phân tách, nhờ dễ unit test, mà ứng dụng Java dễ bảo trì, dễ nâng cấp, dễ bổ sung tính năng.

 

DEPENDENCY LÀ MÔ HÌNH/PHƯƠNG THỨC (DESIGN PATTERN) LẬP TRÌNH, KHÔNG LỆ THUỘC VÀO NGÔN NGỮ LẬP TRÌNH

– Nếu bạn không phải là lập trình viên Java, có dùng Dependency Injection không?
– Có. Là lập trình viên PHP, bạn sẽ thấy Dependency Injection trong Zend Framework [3] [4]. Là lập trình viên Python, bạn sẽ thấy Dependency Injection trong Pinject [5], v.v.. Và nếu bạn không muốn sử dụng Dependency Injection dựng sẵn bởi các framework, bạn có thể tự lập trình theo mô hình này.

[1] https://github.com/google/guice
[2] https://spring.io/team/pwebb
[3] https://github.com/zendframework/zend-di
[4] https://framework.zend.com/manual/2.4/en/tutorials/quickstart.di.html
[5] https://github.com/google/pinject

Đỗ Như Vý  
Software developer


Dependency Injection,
Inversion of Control,
java,
php,
Python,
Spring,
Spring framework,