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

Editors' Choicearrow-up-right

laravel-1.png

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.

Có lẽ đây cũng sẽ là bài viết cuối cùng trong series Laravel Beauty. Hy vọng thông qua series này, các bạn đã có được một cái nhìn tổng thể về kiến trúc của Framework Laravel, cũng như tự ngẫm được ra cho mình những phương pháp, những best practices để có thể sử dụng Laravel một cách thật hiệu quả. 😃

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 Containerarrow-up-rightService Providerarrow-up-right 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ề Facadearrow-up-right.

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.

Trên document của Laravel, Contracts còn được miêu tả là thành phần "serve as succinct documentation to the framework's features" (được coi như là bộ documentation ngắn gọn về các chức năng của Framework). Vì sao ư, bạn có thể hiểu đơn giản là nhìn vào Contract, ta có thể biết được Framework (hay trong nhiều trường hợp cụ thể hơn các Service của Framework) có thể "làm được những gì". Đó chính là thứ chúng ta quan tâm 😄 (bởi thực tế bạn cũng chẳng cần phải biết xem các Service đã "làm như thế nào" để thực hiện các chức năng của chúng đúng không =)), à trừ khi bạn có ý định muốn tìm hiểu kỹ để contribute cho framework thôi)

Về danh sách các Contract này, các bạn có thể tham khảo ở repo chính thức illuminate/contractsarrow-up-right. 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 Laravelarrow-up-right, 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.

Nếu bạn đã nắm rõ về Service Container và Service Provider thì có thể đã thấy được vai trò của Interface từ trước. Ngoài ra, một chút kiến thức cơ bản về các quy tắc thiết kế hướng đối tượng (Object Oriented Design Principlesarrow-up-right) có lẽ cũng sẽ giúp các bạn hiểu thêm về cách sử dụng cũng như tầm quan trọng của Interface đấy 😄

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)

PHParrow-up-rightLaravelarrow-up-rightContractarrow-up-right

All rights reserved

MỤC LỤC


BÀI VIẾT THUỘC SERIES


Laravel: The Beauty1. arrow-up-right2. arrow-up-right3. arrow-up-right4. arrow-up-right5. arrow-up-right

CÁC TỔ CHỨC ĐƯỢC ĐỀ XUẤT


Avatararrow-up-rightNghệ thuật Codingarrow-up-right 18 2 290 38.6KAvatararrow-up-rightVibloarrow-up-right 9 14 135 45.4KAvatararrow-up-rightHUST & PIarrow-up-right 4 1 8 18.1K

Bài viết liên quan

Dependency Injection & PHP Reflection in Laravelarrow-up-rightNgáoarrow-up-right7 phút đọc 1917 2 08Laravel Beauty: Recipes & Best Practicesarrow-up-rightTran Duc Thangarrow-up-right17 phút đọc 18725 115 13137Laravel Beauty: Tìm hiểu về Service containerarrow-up-rightTran Duc Thangarrow-up-right15 phút đọc 27711 85 41161Laravel Beauty: Tìm hiểu về Facadearrow-up-rightTran Duc Thangarrow-up-right12 phút đọc 18800 50 2177Laravel Beauty: Tìm hiểu về Service Providerarrow-up-rightTran Duc Thangarrow-up-right15 phút đọc 26387 44 2497Học Laravel: Service Containerarrow-up-rightNgo Duy Sonarrow-up-right10 phút đọc 2760 15 111Laravel và những điều cần biết - phần 3arrow-up-rightHoàng Hữu Hợiarrow-up-right17 phút đọc 2831 9 03Container trong Laravelarrow-up-rightNguyễn Hoàng Việt Khánharrow-up-right9 phút đọc 1001 7 17Một vòng laravel (Part 4)arrow-up-rightNguyễn Phúc Lươngarrow-up-right9 phút đọc 773 3 07Dependency Injection & PHP Reflection in Laravelarrow-up-rightNgáoarrow-up-right7 phút đọc 1917 2 08Laravel Beauty: Recipes & Best Practicesarrow-up-rightTran Duc Thangarrow-up-right17 phút đọc 18725 115 13137Laravel Beauty: Tìm hiểu về Service containerarrow-up-rightTran Duc Thangarrow-up-right15 phút đọc 27711 85 41161Laravel Beauty: Tìm hiểu về Facadearrow-up-rightTran Duc Thangarrow-up-right12 phút đọc 18800 50 2177Laravel Beauty: Tìm hiểu về Service Providerarrow-up-rightTran Duc Thangarrow-up-right15 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ếtarrow-up-rightTran Duc Thangarrow-up-right22 phút đọc 5691 42 267[Become A SuperUser] Filesystem Hierarchy Standardarrow-up-rightTran Duc Thangarrow-up-right19 phút đọc 1090 14 244Bài toán các vị tướng Byzantine và ứng dụng trong Blockchainarrow-up-rightTran Duc Thangarrow-up-right19 phút đọc 7096 50 1584[Become a SuperUser] Debian vs Redhat: Package Management Systemarrow-up-rightTran Duc Thangarrow-up-right14 phút đọc 2065 19 1135[Become a SuperUser] Manage file permissions and ownershiparrow-up-rightTran Duc Thangarrow-up-right30 phút đọc 401 4 015[Become A SuperUser] Find system filesarrow-up-rightTran Duc Thangarrow-up-right9 phút đọc 232 3 219[Review Sách] Cracking the Coding Interview - 189 Programming Questions & Solutionsarrow-up-rightTran Duc Thangarrow-up-right16 phút đọc 1314 6 129Tìm hiểu về giải thuật Chia để Trị (Divide and Conquer)arrow-up-rightTran Duc Thangarrow-up-right18 phút đọc 3110 10 019Tìm hiểu về giải thuật Đệ Quyarrow-up-rightTran Duc Thangarrow-up-right22 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.arrow-up-rightTran Duc Thangarrow-up-right19 phút đọc 3221 34 158Simple Rules to make your code Cleaner (Part 2)arrow-up-rightTran Duc Thangarrow-up-right22 phút đọc 862 4 212Simple Rules to make your code Cleaner (Part 1)arrow-up-rightTran Duc Thangarrow-up-right15 phút đọc 1133 9 019Một số Design Principles trong lập trình mà bạn nên biếtarrow-up-rightTran Duc Thangarrow-up-right22 phút đọc 5691 42 267[Become A SuperUser] Filesystem Hierarchy Standardarrow-up-rightTran Duc Thangarrow-up-right19 phút đọc 1090 14 244Bài toán các vị tướng Byzantine và ứng dụng trong Blockchainarrow-up-rightTran Duc Thangarrow-up-right19 phút đọc 7096 50 1584[Become a SuperUser] Debian vs Redhat: Package Management Systemarrow-up-rightTran Duc Thangarrow-up-right14 phút đọc 2065 19 1135[Become a SuperUser] Manage file permissions and ownershiparrow-up-rightTran Duc Thangarrow-up-right30 phút đọc 401 4 015[Become A SuperUser] Find system filesarrow-up-rightTran Duc Thangarrow-up-right9 phút đọc 232 3 219[Review Sách] Cracking the Coding Interview - 189 Programming Questions & Solutionsarrow-up-rightTran Duc Thangarrow-up-right16 phút đọc 1314 6 129Tìm hiểu về giải thuật Chia để Trị (Divide and Conquer)arrow-up-rightTran Duc Thangarrow-up-right18 phút đọc 3110 10 019

Bình luận

Đăng nhập để bình luậnAvatararrow-up-rightNgo Duy Son @ngo.duy.sonarrow-up-rightthg 7 25, 2016 5:35 SA

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.

0 |Trả lờiChia sẻarrow-up-rightAvatararrow-up-rightHenry Bui @viethuong2072000arrow-up-rightthg 6 5, 2018 1:33 CH

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.

0 |Trả lờiChia sẻarrow-up-rightAvatararrow-up-rightTran Duc Thang @thangtd90arrow-up-rightthg 6 5, 2018 2:05 CH

Bản thân contract chỉ là Interface thôi bạn ạ. Đơn giản là mình viết các Interface, và gọi nó là Contract 😂

Còn Interface thì như bạn nói, có thể dùng để binding vào Service Container. 😃

0 |Trả lờiChia sẻarrow-up-rightAvatararrow-up-rightHenry Bui @viethuong2072000arrow-up-rightthg 6 5, 2018 3:21 CH

À thì ra là vậy, cảm ơn bạn.

0 |Trả lờiChia sẻarrow-up-rightAvatararrow-up-rightduongricky @duongrickyarrow-up-rightthg 1 4, 2019 2:38 CH

Thực chất contract này giống với interface binding phải k a ??

0 |Trả lờiChia sẻarrow-up-rightAvatararrow-up-rightTran Duc Thang @thangtd90arrow-up-rightthg 1 5, 2019 2:04 CH

uh đúng rồi em 😃 Contract ở đây chỉ là tên gọi cho các Interface thôi 😄

0 |Trả lờiChia sẻarrow-up-rightAvatararrow-up-rightDat Dao @datagitarrow-up-rightthg 1 23, 2019 3:25 CH

good job

0 |Trả lờiChia sẻarrow-up-rightAvatararrow-up-rightHoà Nguyễn @nguyenvanhoa18042000arrow-up-rightthg 5 16, 7:32 CH

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

0 |Trả lờiChia sẻarrow-up-rightAvatararrow-up-rightNguyễn Đức Vinh @nguyenducvinh704arrow-up-rightthg 6 7, 1:45 CH

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.

0 |Trả lờiChia sẻarrow-up-rightAvatararrow-up-rightĐạt Bá @lateonearrow-up-rightthg 8 5, 5:32 CH

Cảm ơn anh, series này của a đã giúp e hiểu rõ laravel hơn.

Last updated