+4

Spring Boot In Action: Depedency Injection and Inversion Of Control

I. DI (Dependency Injection)

DI = Dependency + Injection

1. Dependency

Nói một cách đơn giản thì dependencysự phụ thuộc. Nếu một class A sử dụng một số tính năng của class B thì có nghĩa rằng class A có sự phụ thuộc vào class B.

image.png

Dưới đây là một ví dụ cho thấy sự phụ thuộc. Khi khởi tạo instance của class A thì bạn phải khởi tạo instance của B để sử dụng tính năng của B.

A là dependent class. B là depedency của A.

image.png

Ví dụ 1. Powered by https://carbon.now.sh/

2. Injection

Injection nếu dịch một cách thô thiển có nghĩa là tiêm vào. Rõ ràng là bạn không thể tiêm một cái gì không có sẵn được cho nên hành động injection cần hiểu là depedency đã được khởi tạo và binding bên ngoài depedent class.

image.png

Ví dụ 2. Powered by https://carbon.now.sh/

Có nhiều cách để inject depedency và ở ví dụ trên mình đang dùng constructor injection, một trong những cách làm phổ biến nhất.

3. Programming To Interface (PTI)

Bạn có thể thấy DI cũng chỉ là một kỹ thuật giúp chúng ta khởi tạo depedency của một depedent object có sẵn. Nhưng tóm lại là nó giải quyết vấn đề gì mà bạn đi đâu cũng thấy người ta nói về nó?

image.png

Như ở ví dụ 1, nếu bạn khởi tạo instance của A thì bạn cũng phải khởi tạo instance của B. Mối quan hệ giữa A và B được gọi là tight-coupling. Tuy nhiên ở ví dụ 2 thì ngược lại, nếu B là một interface thì bạn có thể khởi tạo A với bất cứ concrete implementation nào của B. Lúc này mối quan hệ hệ giữa A và B được gọi là loose-coupling (đạt được thông qua sử dụng Programming To Interface).

image.png

Bạn sẽ dễ dàng thấy sự hiệu quả của kĩ thuật này trong kiểm thử phần mềm.

image.png

II. Inversion of Control (IoC)

Bởi vì mọi cái tên được đặt ra đều có ý nghĩa của nó cho nên khi bắt đầu tiếp cận một khái niệm thì mình cứ dịch ngựa ra trước. Inversion of control là đảo ngược sự kiểm soát chăng? Wtf? Kiểm soát là kiểm soát cái gì? Xin thưa rằng đó chính là luồng đi hay flow của code.

Muốn biết hành động đảo ngược luồng đi của code diễn ra như thế nào thì hãy xem lại cách một chương trình thực thi trước khi IoC ra đời thông qua hai ví dụ ở trên. Khi bạn chạy hàm Main, mọi thứ phải được khởi tạo thủ công từ trên xuống dưới, từng dòng một. Tuy nhiên với đoạn code Spring Boot sau đây bạn sẽ trải nghiệm một điều hoàn toàn khác biệt.

image.png

Chúng ta không có bất cứ một từ khóa new nào được sử dụng cả, cũng không cần phải khởi tạo depedency object B hay tự inject B vào depedent object A.. mà chính Ioc Container sẽ làm những điều đó hộ chúng ta.

IoC được giới thiệu lần đầu vào năm 1988 được phát biểu như sau:

One important characteristic of a framework is that the methods defined by the user to tailor the framework will often be called from within the framework itself, rather than from the user’s application code. The framework often plays the role of the main program in coordinating and sequencing application activity. This inversion of control gives frameworks the power to serve as extensible skeletons. The methods supplied by the user tailor the generic algorithms defined in the framework for a particular application.

Đại khái là luồng đi của chương trình sẽ do framework điều phối. Code của user sẽ do framework tự gọi.

Ý nghĩa của Inversion Of Control có nghĩa rằng thay vì chúng ta phải tự gọi method, làm mọi thứ một cách tuần tự thì sẽ có ai đó làm hộ chúng ta như Spring Boot chẳng hạn.

The major difference between an object-oriented framework and a class library is that the framework calls the application code. Normally the application code calls the class library. This inversion of control is sometimes named the Hollywood principle, “Do not call us, we call You”.

Michael Mattson

Có thể thấy rằng, ở ví dụ trên chúng ta đã chạm đến nguyên lý thiết kế Inversion Of Control thông qua kỹ thuật Depedency Injection. Hy vọng rằng đến đây mọi người có thể nắm được bản chất của DI và IoC.

III. Bean

image.png

Instance của class A và class B ở đây trong Spring Boot được gọi là bean, việc của chúng ta đơn giản là sử dụng còn việc khởi tạo và quản lý thì IoC Container sẽ làm thông qua những kỹ thuật nêu trên.

image.png

Vì các nhu cầu customize bean khác nhau như khi khởi tạo inject depedency phải đúng thứ tự để tránh NPE/custom logic/disconnect DB sau khi sử dụng... nên bean cũng có life cycle của riêng nó để giúp cho việc sử dụng bean một cách hiệu quả nhất có thể.

image.png

Thanks for reading.

References


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.