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' Choice

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.

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 ContainerService 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.

// Dependency Injection Style
class Something
{
    protected $mailer;

    public function __constructor(Illuminate\Contracts\Mail\Mailer $mailer)
    {
        $this->mailer = $mailer;
    }

    public function sendMail()
    {
        // Sending mail
        $this->mail->send($view, $data);
    }
}

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)

PHPLaravelContract

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