Laravel Beauty: Tìm hiểu về Contract
https://viblo.asia/p/laravel-beauty-tim-hieu-ve-contract-oZVRg4mpMmg5
Laravel Beauty: Tìm hiểu về Contract
Index
Mở đầu
Tiếp nối series về các phần core của Laravel Framework, trong bài viết này, mình sẽ giới thiệu nốt về thành phần cuối cùng được nhắc tới trong mục Architecture Foundations của Laravel, bên cạnh những Service Container, Service Provider, Facade.
Đó chính là Contract.
Tìm hiểu về Contract
Contract là gì?
Contract dịch ra tiếng Việt thì có nghĩa là "hợp đồng". Các thành phần của Laravel làm việc và liên kết với nhau thông qua các "hợp đồng" đó.
Thực ra, "Contract" chỉ là thuật ngữ được Taylor Otwell, cha đẻ của Laravel, cũng như các đồng nghiệp của ông lựa chọn để là tên gọi cho một phần trong kiến trúc framework của mình từ phiên bản Laravel 5.0 mà thôi, chứ thực tế, bản chất của Contract là các ... Interface.
Thuật ngữ Contract này cũng không phải là mới mẻ gì, hay do Taylor nghĩ ra, mà nó vốn đã được sử dụng rất nhiều và phổ biến trong các ngôn ngữ lập trình hướng đối tượng, để chỉ Interface hay Abstract Class.
Việc sử dụng Interface sẽ giúp ta phát huy được tính đa hình của lập trình hước đối tượng, đó cũng chính là chìa khoá để có được một hệ thống thiết kế tốt, một well-designed-application.
Sử dụng Contract
Nếu đã từng xem qua và nắm vững về Service Container và Service Provider trong những bài viết trước của mình, chắc hẳn bạn vẫn còn nhớ rằng người ta vẫn thường dùng Service Container để bind
một interface
với một implementation
của nó. Việc sử dụng interface như vậy giúp ta dễ dàng thay đổi implementation mà không làm ảnh hưởng gì đến tính đúng đắn của chương trình.
Đến đây hãy nhắc lại về Dependency Injection, khái niệm mình đã nhắc đến rất nhiều lần trong những bài viết thuộc series Laravel Beauty này, để thấy được Contract đang được sử dụng như thế nào trong Laravel nhé.
Đây là ví dụ được đưa ra ở phần cuối bài viết về Facade.
Như các bạn đã biết thì Laravel, với sức mạnh của Service Container sẽ có thể tự động resolve ra một instance $mailer
cho chúng ta. Nhưng vấn đề là chúng ta đang type-hint một Interface (Contract), chứ không phải là một class cụ thể. Thực tế logic của chúng ta cũng không cần biết và quan tâm đến cái class gửi mail nó là class gì, hay nó đã làm thế nào để có thể gửi mail. Cái duy nhất logic của ta quan tâm là nó cần một instance có thể gửi mail để hoạt động. Đó là instance của class nào không quan trọng, miễn là class đó có implement interface Illuminate\Contracts\Mail\Mailer
.
Hay nói cách khác, code của chúng ta không phụ thuộc vào một implementation (một concrete class) nào cụ thể cả, mà nó phụ thuộc vào một cái "hợp đồng" Mailer
thôi.
Ngoài ra, nếu không muốn sử dụng Service Mailer có sẵn mà Laravel cung cấp, ta có thể tự viết ra một Service của riêng mình, đương nhiên là nó sẽ phải "thoả mãn" cái "hợp đồng" (phải implement cái interface) Illuminate\Contracts\Mail\Mailer
rồi. Tiếp sau đó ta tiến hành bind cái contract Illuminate\Contracts\Mail\Mailer
với cái Service của mình vừa viết vào trong Service Container, và thế là xong. Những công việc còn lại Laravel đã lo hết cho chúng ta. =))
Contract trong Laravel
Contract xuất hiện ở mọi ngõ ngách trong Laravel Framework.
Về danh sách các Contract này, các bạn có thể tham khảo ở repo chính thức illuminate/contracts. Vào đấy bạn sẽ thấy lượng Contract của Laravle nó đồ sộ đến thế nào =))
Còn khi bạn xây dựng application của mình trên nền tảng Laravel, thì mặc dù thư mục Contracts
không có sẵn, nhưng bạn có thể tự tạo ra một thư mục như thế, có thể là bên trong thư mục app
, hay bên trong các folder khác nữa, rồi đặt các Interface
của mình vào, cho nó giống với Laravel Style. :v
Đương nhiên bạn vẫn có thể tạo được ra một trang web mà không cần biết đến Contract
là gì, hay cảm thấy quá bất tiện khi phải đi mò xem cái interface mình cần nó ở đâu nên không dùng đến. Bạn thấy mình vẫn có thể thực hiện Dependency Injection mặc dù không cần dùng đến Interface, mà thay vào đó là type-hint tên class cụ thể, đấy thôi. (đương nhiên thì trong phần lớn các trường hợp thì nó là một cách thức tồi rồi =)))
Hoặc là đôi khi bạn có thể dùng đến một "vũ khí" đầy sức mạnh khác của Laravel mà mình cũng đã đề cập ở phần trước, đó chính là Facade.
Bản thân Facade
cũng có quan hệ mật thiết với Contract
. Bởi Facade cũng chỉ là một công cụ che đi việc resolve ra service từ Service Container. Tức bạn thay đổi đối tượng binding của Contract với Service Container thì đối tượng phía bên dưới Facade (service mà Facade resolve ra) cũng sẽ thay đổi. Các bạn có thể kiểm tra xem danh sách Contract, với Facade tương ứng với nó ở trang document của Laravel, từ đó bạn sẽ có thể biết được rằng "nếu mình không muốn dùng Facade này, thì mình phải dùng Dependency Injection với Contract nào để thay thế, và ngược lại".
Lời kết
Như vậy là mình đã giới thiệu qua về Contract, cũng như vai trò của nó trong kiến trúc của Laravel Framework.
Thực tế thì Contract cũng khá là đơn giản, dễ hiểu, nên thật sự cũng không có nhiều điều để mà nói về nó cả. =))
Contract trong Laravel đơn giản chỉ là Interface.
Hy vọng có đã có thể giúp các bạn thêm hiểu, và thêm yêu quý framework PHP tuyệt vời này. (dance2)
All rights reserved
MỤC LỤC
BÀI VIẾT THUỘC SERIES
Laravel: The Beauty1. 2. 3. 4. 5.
CÁC TỔ CHỨC ĐƯỢC ĐỀ XUẤT
Bài viết liên quan
Dependency Injection & PHP Reflection in LaravelNgáo7 phút đọc 1917 2 08Laravel Beauty: Recipes & Best PracticesTran Duc Thang17 phút đọc 18725 115 13137Laravel Beauty: Tìm hiểu về Service containerTran Duc Thang15 phút đọc 27711 85 41161Laravel Beauty: Tìm hiểu về FacadeTran Duc Thang12 phút đọc 18800 50 2177Laravel Beauty: Tìm hiểu về Service ProviderTran Duc Thang15 phút đọc 26387 44 2497Học Laravel: Service ContainerNgo Duy Son10 phút đọc 2760 15 111Laravel và những điều cần biết - phần 3Hoàng Hữu Hợi17 phút đọc 2831 9 03Container trong LaravelNguyễn Hoàng Việt Khánh9 phút đọc 1001 7 17Một vòng laravel (Part 4)Nguyễn Phúc Lương9 phút đọc 773 3 07Dependency Injection & PHP Reflection in LaravelNgáo7 phút đọc 1917 2 08Laravel Beauty: Recipes & Best PracticesTran Duc Thang17 phút đọc 18725 115 13137Laravel Beauty: Tìm hiểu về Service containerTran Duc Thang15 phút đọc 27711 85 41161Laravel Beauty: Tìm hiểu về FacadeTran Duc Thang12 phút đọc 18800 50 2177Laravel Beauty: Tìm hiểu về Service ProviderTran Duc Thang15 phút đọc 26387 44 2497
Bài viết khác từ Tran Duc Thang
Một số Design Principles trong lập trình mà bạn nên biếtTran Duc Thang22 phút đọc 5691 42 267[Become A SuperUser] Filesystem Hierarchy StandardTran Duc Thang19 phút đọc 1090 14 244Bài toán các vị tướng Byzantine và ứng dụng trong BlockchainTran Duc Thang19 phút đọc 7096 50 1584[Become a SuperUser] Debian vs Redhat: Package Management SystemTran Duc Thang14 phút đọc 2065 19 1135[Become a SuperUser] Manage file permissions and ownershipTran Duc Thang30 phút đọc 401 4 015[Become A SuperUser] Find system filesTran Duc Thang9 phút đọc 232 3 219[Review Sách] Cracking the Coding Interview - 189 Programming Questions & SolutionsTran Duc Thang16 phút đọc 1314 6 129Tìm hiểu về giải thuật Chia để Trị (Divide and Conquer)Tran Duc Thang18 phút đọc 3110 10 019Tìm hiểu về giải thuật Đệ QuyTran Duc Thang22 phút đọc 8558 6 018Cùng ôn lại các khái niệm về Cấu trúc dữ liệu, Giải thuật, Độ phức tạp thuật toán.Tran Duc Thang19 phút đọc 3221 34 158Simple Rules to make your code Cleaner (Part 2)Tran Duc Thang22 phút đọc 862 4 212Simple Rules to make your code Cleaner (Part 1)Tran Duc Thang15 phút đọc 1133 9 019Một số Design Principles trong lập trình mà bạn nên biếtTran Duc Thang22 phút đọc 5691 42 267[Become A SuperUser] Filesystem Hierarchy StandardTran Duc Thang19 phút đọc 1090 14 244Bài toán các vị tướng Byzantine và ứng dụng trong BlockchainTran Duc Thang19 phút đọc 7096 50 1584[Become a SuperUser] Debian vs Redhat: Package Management SystemTran Duc Thang14 phút đọc 2065 19 1135[Become a SuperUser] Manage file permissions and ownershipTran Duc Thang30 phút đọc 401 4 015[Become A SuperUser] Find system filesTran Duc Thang9 phút đọc 232 3 219[Review Sách] Cracking the Coding Interview - 189 Programming Questions & SolutionsTran Duc Thang16 phút đọc 1314 6 129Tìm hiểu về giải thuật Chia để Trị (Divide and Conquer)Tran Duc Thang18 phút đọc 3110 10 019
Bình luận
Một series quá tuyệt vời! Tự hào là người theo hết từ đầu tới cuối (yeah3) Mong rằng sau này anh sẽ viết thêm nhiều bài về Laravel hơn nữa.
Cả 4 phần có mỗi phần cuối này hơi khó hiểu một chút. Theo mình hiểu thì Contract thực ra là cách hiện thực Interface Binding của Service Container, không biết như vậy có đúng không bạn.
À thì ra là vậy, cảm ơn bạn.
Thực chất contract này giống với interface binding phải k a ??
good job
Em phải tạo tài khoản để cảm ơn bác về series này. Nó giúp e hiểu ra nhiều thứ. Cảm ơn bác rất nhiều, chúc bác luôn mạnh khoẻ và thành công
Cảm ơn anh, seri này giúp em hiểu rõ về cách hoạt động core của laravel hơn.
Cảm ơn anh, series này của a đã giúp e hiểu rõ laravel hơn.
Last updated