Dependency Injection
Nhận thấy lần trước bài về CommandBus Design Pattern nhận được phản ứng tốt của mn, nên mình đang có ý tưởng về một serie các bài xoay quanh chủ đề các Design Pattern đơn giản có thể áp dụng, cũng như củng cố các khái niệm về OOP hay SOLID cho các bạn mới bắt đầu. Mọi thứ sẽ không viết theo kiểu hàn lâm, nhiều khái niệm khó hiểu, mà sẽ cố gắng bằng một giọng văn gần gũi và các ví dụ đơn giản dễ thực hiện (Vì implement các Design Pattern thì nó đã có đầy rẫy trên mạng rồi)
- Warning 1: Các bài viết luôn xoay quanh quan điểm thiết kế hướng đối tượng (OOP). Nếu bạn là fan của FP thì nó sẽ không phù hợp.
- Warning 2: Mục tiêu của người viết thuần túy là chia sẻ kiến thức, xây dựng cộng đồng và group. Nếu bạn đã biết có thể bỏ qua (Vì các bài viết của mình luôn chỉ là các kiến thức cơ bản). Nếu có gì không đúng, mong mn comment mang tính xây dựng (Mình sẽ không trả lời các comment dạng: "Senior đây, khuyên thật đừng làm như thế này"). Chúng ta chia sẻ để giúp nhau phát triển, không phải dạy đời nhau.
BÀI 1: DESIGN PATTERN LÀ GÌ ?, VÌ SAO CẦN HỌC DESIGN PATTERN ?. GIỚI THIỆU DEPENDENCY INJECTION.
Để học một cái gì đó bạn cần phải trả lời được lý do vì sao bạn cần phải học nó. Nếu không thì nó hoàn toàn là học vẹt (Vì học chẳng để làm gì). Vậy Design Pattern là gì ?. Về cơ bản, DP là tập hợp các mẫu thiết kế, các công thức đã được chứng minh là hiệu quả trong các tình huống cụ thể, giúp người xây dựng phần mềm tiết kiệm thời gian, tăng hiệu quả và dễ dàng "bảo trì bảo dưỡng" ứng dụng. Khái niệm DP thực ra đã có từ rất lâu ở các ngành nghề khác, và các mẫu thiết kế trong OOP chỉ là các ánh xạ vào lập trình.
Ví dụ minh họa kinh điển là cách thiết kế "bóng đèn - đui đèn": Một mẫu thiết kế tốt cho phép bạn linh hoạt thay đổi giữa bóng và đui, trong khi thiết kế tồi khiến cái đèn của bạn không thể thay thế (tight coupling) => bạn buộc phải mua một cái đèn mới, thay vì chỉ cần thay bóng. Hãy tưởng tượng cái đèn nhà vệ sinh của mình bị hỏng, và nếu phải thay tuốt tuồn tuột từ trên xuống dưới thì thực sự là cơn ác mộng !
Thành thạo các design pattern cơ bản là điều kiện tiên quyết để bạn phát triển kỹ năng coding của mình
DEPENDENCY INJECTION
DI là giải pháp thiết kế cho chính bài toán bóng đèn - đui đèn bên trên. Nếu bạn làm Laravel, chắc chắn bạn đã nằm lòng khái niệm Service Container - một cái hộp thần kỳ giúp ứng dụng của bạn trở nên uyển chuyển một cách thú vị thông qua việc binding các lớp trừu tượng. Tuy nhiên, nếu bạn là người mới bắt đầu, hầu hết chúng ta chỉ cảm nhận DI qua việc inject interface từ __construct, binding trong ServiceContainer. Rất nhiều bạn thắc mắc rốt cuộc DI có gì hơn việc sử dụng từ khóa new trong chính class đó (Việc inject nhiều thực sự là rối rắm, đúng không ?).
Về cốt lõi, DI đại diện cho triết lý "Composition Over Inheritance". Một đối tượng nên được tạo thành từ các viên gạch nhỏ hơn từ bên ngoài, thay vì chúng ta tự khởi tạo trong chính đối tượng đó. Hãy quay trở lại với ví dụ trên: Nếu ta đã có một cái đui, ta có thể inject bất kỳ cái đèn nào vào cái đui đó để thu được một cái đèn như ý muốn. Cần đèn xanh, có. Cần đèn vàng, có. Cần đèn nhấp nháy, easy (Đoạn này nghe quen quen phải không, DI giúp chúng ta tạo nên tính Đa hình (Polymorphism). Ta có thế chế ra đủ loại đèn mà mình muốn). Nếu cái đui gắn chặt vào một cái đèn (giống như nó tự khởi tạo new một cái đèn bên trong nó), rõ ràng là rất tồi tệ (ko thể thay đèn mà sẽ phải vứt nguyên mua cái mới). Khi ta tách được đèn và đui, việc của chúng ta là thiết kế một lớp trừu tượng, ở đây chính là cái trôn để xoáy đèn vào đui của nó. Cái đèn chỉ cần "implement" "interace trôn đèn", và miễn là nó implemnt interface này, nó sẽ luôn xoáy được vào đui, và chắc chắn nó sẽ hoạt động được. Rất trực quan và dễ hiểu đúng không các bạn ?
DI giúp bạn test dễ hơn nhiều. Tôi muốn test cái đui, hoặc đèn, tôi có sẵn đèn mẫu (Mocking Object), cắm vô, sáng => Pass Test. Nếu không có DI, thì class sẽ rất khó để test được.
Việc áp dụng triệt để triết lý này khi code giúp chúng ta có tư duy phân tách code thành các đơn vị nhỏ, để lắp ghép nó thành những cái đèn của chúng ta. Nhiều cái đèn thì có thể làm thành một ngọn hải đăng chẳng hạn. Và nếu có cái đèn nào vỡ / hỏng (bug), ta dễ dàng cô lập, thay thế, và sửa chữa nó.
Mình sẽ không chia sẻ code mẫu ở đây, vì chắc chắn các bạn đang áp dụng nó hàng ngày. Bài viết này mục đích gợi mở ban đầu về serie mình định làm, nếu có gì chưa đúng, cần cải thiện, mời các bạn đóng góp xây dựng, để chúng ta chia sẻ được kiến thức, giúp các bạn mới khởi đầu chắc chắn hơn trong sự nghiệp. Nếu được 200 likes, chúng ta sẽ có bài tiếp theo nhé :)). Cám ơn mn