Tìm hiểu về Laravel Facade

Tram Ho

Introduction

Hẳn đối với bất cứ ai từng làm việc với Laravel framework đều đã sử dụng đến Facade. Đây có lẽ là một trong các tính năng hữu ích nhất cho quá trình phát triển phần mềm của bạn.
Với một cú pháp đơn giản gọn nhẹ, nó có thể sử dụng hiệu quả ngay cả khi ta không thực sự hiểu rõ cách hoạt động của chúng. Tuy nhiên, cũng chính vì vậy, nhiều người có thể hiểu lầm về cách làm việc của Facades. Trong bài viết này chúng ta sẽ đi vào tìm hiểu chi tiết về Facades và cách chúng thực sự hoạt động.

Mục lục

I. What is Facade?

II. How to use it?

III. How does it work?

IV. Tổng kết

I. What is Facade?

Facade là một Design Pattern sử dụng trong lập trình hướng đối tượng. Giống như mặt tiền của một tòa nhà, facade trong lập trình có thể hiểu như một giao diện thay cho các kiến trúc phức tạp bên trong một hệ thống. Qua đó cho phép:

  • Dễ dàng đọc và sử dụng bằng cách ẩn các cài đặt phức tạp của thư viện dưới một lớp giao diện đơn giản.
  • Giảm sự phụ thuộc giữa các khối lệnh nhờ sự tương tác thông qua giao diện thay vì chính hệ thống.
  • Đóng gói các API phức tạp thành một hệ thống gọn gàng.

Facade trong Laravel cung cấp cho chúng ta một giao diện các phương thức “tĩnh” đơn giản dễ hiểu tới tính năng của các service trong Laravel như Auth, Mail, Notification,v.v… nhưng đồng thời duy trì tính mềm dẻo và khả năng kiểm thử của một phương thức non-static.

II. How to use it?

Tất cả các Facade của Laravel được định nghĩa trong namespace IlluminateSupportFacades và có thể sử dụng như sau:

Bên cạnh đó, Laravel cũng bao gồm các Helper giúp thực hiện tác nhiệm vụ đơn giản tương ứng như facade.

VD:

Danh sách các Facade của Laravel:

FacadeClassService Container Binding
AppIlluminateFoundationApplicationapp
ArtisanIlluminateContractsConsoleKernelartisan
AuthIlluminateAuthAuthManagerauth
Auth (Instance)IlluminateContractsAuthGuardauth.driver
BladeIlluminateViewCompilersBladeCompilerblade.compiler
BroadcastIlluminateContractsBroadcastingFactory
Broadcast (Instance)IlluminateContractsBroadcastingBroadcaster
BusIlluminateContractsBusDispatcher
CacheIlluminateCacheCacheManagercache
Cache (Instance)IlluminateCacheRepositorycache.store
ConfigIlluminateConfigRepositoryconfig
CookieIlluminateCookieCookieJarcookie
CryptIlluminateEncryptionEncrypterencrypter
DBIlluminateDatabaseDatabaseManagerdb
DB (Instance)IlluminateDatabaseConnectiondb.connection
EventIlluminateEventsDispatcherevents
FileIlluminateFilesystemFilesystemfiles
GateIlluminateContractsAuthAccessGate
HashIlluminateContractsHashingHasherhash
HttpIlluminateHttpClientFactory
LangIlluminateTranslationTranslatortranslator
LogIlluminateLogLogManagerlog
MailIlluminateMailMailermailer
NotificationIlluminateNotificationsChannelManager
PasswordIlluminateAuthPasswordsPasswordBrokerManagerauth.password
Password (Instance)IlluminateAuthPasswordsPasswordBrokerauth.password.broker
QueueIlluminateQueueQueueManagerqueue
Queue (Instance)IlluminateContractsQueueQueuequeue.connection
Queue (Base Class)IlluminateQueueQueue
RedirectIlluminateRoutingRedirectorredirect
RedisIlluminateRedisRedisManagerredis
Redis (Instance)IlluminateRedisConnectionsConnectionredis.connection
RequestIlluminateHttpRequestrequest
ResponseIlluminateContractsRoutingResponseFactory
Response (Instance)IlluminateHttpResponse
RouteIlluminateRoutingRouterrouter
SchemaIlluminateDatabaseSchemaBuilder
SessionIlluminateSessionSessionManagersession
Session (Instance)IlluminateSessionStoresession.store
StorageIlluminateFilesystemFilesystemManagerfilesystem
Storage (Instance)IlluminateContractsFilesystemFilesystemfilesystem.disk
URLIlluminateRoutingUrlGeneratorurl
ValidatorIlluminateValidationFactoryvalidator
Validator (Instance)IlluminateValidationValidator
ViewIlluminateViewFactoryview
View (Instance)IlluminateViewView

III. How does it work?

Trong ví dụ nêu trên ta thấy hàm get() của Facade Cache được gọi như một phương thức tĩnh: Cache::get('key').

Mặc dù nhìn qua, Facade có vẻ chỉ đơn thuần là các phương thức tĩnh được gọi thông qua các class như Mail, Auth, Cache, v.v… Nhưng thực tế, khi chúng ta nhìn vào bất cứ class cài đặt nào trong danh sách nêu trên ta đều nhận thấy chúng hoàn toàn là các phương thức bình thường.

VD: Phương thức get() của Facade Cache thực chất được cài đặt như sau.

Vậy làm thế nào để Laravel có thể thực hiện được điều này? Để dễ dàng hiểu cách hoạt động của một Facade sau đây ta sẽ đi vào một ví dụ cụ thể đối với facade cache.

Tìm class IlluminateSupportFacadesCache ta nhận thấy nó kế thừa abstract class IlluminateSupportFacadesFacade và thực hiện overwrite hàm getFacadeAccessor() để trả về tên container tương ứng với facade.

VD:

Dựa vào đó Laravel sẽ xác định được Facade này sẽ làm việc như thế nào. Trong CacheServiceProvider, instance của CacheManager đã được bind vào container cache sử dụng Service Container. Khi facade được gọi, instance đó sẽ được ressolve thông qua hàm resolveFacadeInstance() thay vì phải khởi tạo một cách phức tạp các service cần thiết. Qua đó, ta có thể gọi hàm get('key') của CacheManager thông qua Cache như sau:

Khi người dùng gọi tới hàm static không tồn tại get('key') của facade Cache như trên, PHP sẽ thực hiện magic method __callStatic() nhận vào hai giá trị gồm tên phương thức và tham số truyền vào.

VD: Khi gọi phương thức Cache::get('key') hàm __callStatic() sẽ có $methodget$args'key'.

Tại đây Facade sẽ thực hiện lấy ra instance của service tương ứng và thực hiện gọi tới hàm non-static như một phương thức thông thường.

Như ta có thể thấy thông qua ví dụ trên, bằng các khéo léo sử dụng magic method __callStatic() kết hợp với Service Container, Facade đã cung cấp một giao diện đơn giản dễ sử dụng cho các service của Laravel nhưng vẫn duy trì các ưu điểm của phương thức non-static như khi ta thực hiện DI.

IV. Tổng kết

Vậy qua đây chúng ta đã đi vào tìm hiểu chi tiết cách hoạt động của Facade, một công cụ vô cùng hữu ích trong phát triển phần mềm sử dụng Laravel framework. Nếu có nội dung chưa rõ ràng mong mọi người góp ý để cải thiện bài viết.

References

Laravel Documentation Facade: https://laravel.com/docs/8.x/facades#introduction

Laravel Documentation Service Container: https://laravel.com/docs/8.x/container

Facade Pattern: http://wiki.c2.com/?FacadePattern

PHP Magic method: https://www.php.net/manual/en/language.oop5.overloading.php#object.callstatic

Chia sẻ bài viết ngay

Nguồn bài viết : Viblo