Interface and Repository in Laravel

Image for post
Image for post

Bài viết nói về việc cách sử dụng Interface và mẫu thiết kế Repository (Repository pattern).

Đi thẳng luôn vào ví dụ luôn nhé.

Trong laravel, giả thiết mình đã có một model tên là Contact, mình muốn lấy danh sách tất cả các contact có trong db thì mình làm như sau:

Cách viết trên là cách viết thông thường dành cho những người mới bắt đầu, và nó chẳng hề sai chút nào, nhưng về thiết kế nó là một ý tưởng …. tồi. Lý do vì sao:

  • Model bị gắn chặt vào Controller
  • Rất khó để test
  • khó khăn trong bảo trì, nếu muốn sửa đổi model Contact, thì hầu như trong Controller, chỗ nào có sử dụng model này, ta đều phải sửa lại, và đó thật là điều khó đỡ.

Ý tưởng ở đây để giải quyết vấn đề này là ta sẽ sử dụng Repository để tách Model và Controller ra, để khi có thay đổi của Model thì ta chỉ cần thay đổi ở Repo mà thôi.

Xong, ý tưởng trên khá oke, ta chỉ cần viết trong Controller như sau:

Nhưng…có một số vấn đề trong đoạn code trên:

  • Trong trường hợp này, bạn nên tránh việc sử dụng từ khóa “new” nhiều nhất có thể
  • Bạn vẫn gọi đến một Repo cụ thể.

Giải pháp:

  • Sử dụng Dependency Injection, thay vì bạn tạo trực tiếp đối tượng “new ContactRepository”, thì bạn có thể inject trực tiếp vào constructor.
  • Sử dụng Interface

Ví dụ việc sử dụng Interface:

Sử dụng Dependency Injection:

Bạn tự hỏi? Làm sao chúng ta có thể inject ContactInterface vào construct thế kia được. Laravel đã giúp bạn tới tận răng rồi.

Và đây là ý tưởng xuất sắc hơn ở trên:

Đã dừng lại được chưa ??? Nhìn vào giải pháp trên thì thấy khá tuyệt phải không.

Hãy để mình thêm một ví dụ nữa:

Viết lại ContactInterface ở trên:

Hệ thống nào thì hệ thống, cũng phải có quản lý user chứ nhỉ, thêm cái UserInterface cho biết mặt:

Nhân tiện có User rồi, mình thêm 1 JobInterface nữa chẳng hạn:

Khoan đã….

Đậu má, Tại sao lại lặp lại như vậy?

À hay rồi, mình sẽ lại tạo thêm 1 cái BaseInterface để cho bọn nàyExtends là được chứ gì:

Bây giờ thì Extends nào:

Nếu vậy thì tuyệt vời hơn là mình sẽ tạo thêm một cái BaseRepository, dĩ nhiên rồi đúng không:

Không thể chờ thêm được nữa, extends ngay nào, và điều tuyệt vời nhất là đây:

Không thể tin được, các bạn có thấy nếu mỗi lần có thêm một Model mới, ta chỉ cần tạo biến, thay vì viết lại các hàm như ở trên không ? Awesome

Trong Laravel, có một vấn đề mà các bạn chắc chắn đã gặp, hoặc chưa

Đó là vấn đề về N+1. Vấn đề được Laravel giải quyết bằng eager loading.

Vậy thực hiện trong Repo thế nào đây?

Đừng vội, có ví dụ ngay đây

Quá tuyệt phải không ? No đã khiến bạn yêu nó ngay từ cái nhìn đầu tiên chưa?

Chắc chưa đâu, mới là cảm nắng thôi mà. Chờ bài tiếp theo nhé, mình nghĩ sẽ đủ sức mang đến “tình yêu sét đánh” cho bạn đấy. 😁

Bye 😀

19/04/2018

Written by

Be Curious!| ☕️+✍🏼=❤️ | buihuycuong.com

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store