7 phút để hiểu rõ Dependency Injection và ứng dụng nó trong Scala với Macwire

60 giây đầu tiên: Ôn lại kiến thức

Xin chào các bạn! Chắc hẳn trong số chúng ta ai cũng đã từng sử dụng các thư viện, đoạn mã áp dụng Dependency Injection nhưng mọi người thường ít quan tâm tới mục đích, ý nghĩa và vai trò của nó trong hệ thống. Hôm nay mình cùng đi tìm hiểu kỹ càng hơn về khái niệm Dependency Injection nhé.

Hồi còn trên ghê nhà trường, thầy của mình luôn nhắc nhở rằng: “Một hệ thống được thiết kế tốt phải đảm bảo tính Loose Coupling.”.
Coupling chính là sự phụ thuộc giữa các modules, components hay classes (từ sau sẽ gọi chung là modules) với nhau. Loose Coupling đề cập đến sự ít phụ thuộc, ít ràng buộc giữa các modules với nhau, thay đổi thành phần này ít ảnh hưởng tới phần khác, điều này làm cho khâu phát triển độc lập và kiểm thử và bảo trì từng module dễ dàng hơn.
Điều này khá tương đồng với Nguyên lý cuối cùng trong SOLID :  Dependency Inversion principle

  1. High-level modules should not depend on low-level modules. Both should depend on abstractions (e.g., interfaces).
  2. Abstractions should not depend on details. Details (concrete implementations) should depend on abstractions.

3 phút giải thích về Dependency Injection

ioc-and-mapper-in-c-6-638

Mình thường hay lẫn lộn 3 khái niệm Dependency Inversion, Inversion of Control, Dependency Injection vì nghe na ná nhau. Để phân biệt rạch ròi, ta có thể phân biệt chúng như sau:
Dependency Inversion: là một principle
Inversion of Control: là một Pattern tuân thủ nguyên lý Dependency Inversion ở trên, nó có thể thực hiện theo nhiều phương pháp như Service Locator, Event-driven, Delegate,… Dependency Injection là một trong số chúng.
Dependency Injection: là một phương pháp thực hiện Inversion of Control, trong đó module phụ thuộc (dependency) được inject vào module cấp cao dùng tới nó.

Vẫn chưa rõ ràng lắm nhỉ, ta xem qua đoạn code mẫu nham nhảm trên mạng như sau:

Car đang bị phụ thuộc vào Wheels, Battery điều gì xảy ra nếu đó không phải là MRFWheels mà là BMWWheels,… Phải tạo ra dependency mới là BMWWheels để thay thế?

Dependency Injection là một phương pháp nhằm ngăn sự phụ thuộc trên, như một kẻ trung gian để tạo ra các dependencies, từ đó Car trở nên không phụ thuộc vào bất kỳ loại Wheels hay Battery nào đi nữa.

Đôi nét về Macwire trong Scala

Macwire là một DI library của Scala, sử dụng Scala Macros. Nó giúp tiết kiệm thời gian viết đoạn mà DI bằng tay, cung cấp nhiều cách thức triển khai DI khác nhau.
Cùng xem qua ví dụ về DI với Macwire:
nó sẽ generate ra như sau:

Một vài ưu điểm của Macwire:
1. Syntax đơn giản, đoạn mã generate code được check bởi Scala Compiler lúc compile-time.
2. Cơ chế Auto-wiring: như ví dụ trên, nó sẽ tự những tham số cần thiết của UserFinder, UserStatusReader.
3. Val vs Lazy val
4. Có thể sử dụng implicit parameters
Và nó còn nhiều ưu điểm khác nữa mọi người có thể tham khảo ở đây: DocumentsGuide.

Bài viết hơi dài, cảm ơn mọi người đã dành thời gian để đọc.
Tham khảo:
https://codelearn.io/sharing/hieu-ro-ve-dependency-injection
Dependency Injection và Inversion of Control – Phần 1: Định nghĩa
Dependency Injection và Inversion of Control – Phần 2: Áp dụng DI vào code
https://github.com/softwaremill/macwire#how-wiring-works
http://di-in-scala.github.io/

Add a Comment

Scroll Up