Hướng dẫn facade php - mặt tiền php
Index
Mở đầuThông qua các bài viết trước đây trong series Laravel Beauty, mình đã giới thiệu đến các bạn hai khái niệm cơ bản được sử dụng trong Laravel là Service Container và Service Provider. Đây là hai khái niệm trung tâm cần nắm vững khi muốn tìm hiểu sâu về những chức năng khác của Laravel.Laravel Beauty, mình đã giới thiệu đến các bạn hai khái niệm cơ bản được sử dụng trong Laravel là Service Container và Service Provider. Đây là hai khái niệm trung tâm cần nắm vững khi muốn tìm hiểu sâu về những chức năng khác của Laravel. Và trong bài viết lần này, ta sẽ cùng đi tìm hiểu về một tính năng chắc hẳn các bạn đã, và vẫn hay dùng trong các project của mình, và nó chỉ có thể giải thích bằng những hiểu biết về Service Container cũng như Service Provider. Thế nên nếu bạn còn chưa hiểu rõ về hai khái niệm trên thì hãy dành chút thời gian xem lại các bài viết trước trong serie Laravel Beauty này nhé.Service Container cũng như Service Provider. Thế nên nếu bạn còn chưa hiểu rõ về hai khái niệm trên thì hãy dành chút thời gian xem lại các bài viết trước trong serie Laravel Beauty này nhé. Còn nếu bạn đã sẵn sàng thì ta hãy cùng bắt đầu nào Facade là gì?Nếu bạn thích tìm hiểu về Design Patterns, và đã từng xem qua cuốn sách nổi tiếng Design Patterns: Elements of Reusable Object-Oriented Software của "Gang of Four", thì bạn có thể sẽ biết đến Facade Pattern, nằm trong nhóm Structural.Structural. Tuy nhiên, khái niệm Facade trong Laravel ... hoàn toàn không liên quan gì đến Facade Pattern được đề cập đến trong cuốn sách của Gang of Four nhé. =)) Giới thiệu thế để các bạn đỡ nhầm lẫn sau này thôi. =))Facade trong Laravel ... hoàn toàn không liên quan gì đến Facade Pattern được đề cập đến trong cuốn sách của Gang of Four nhé. =)) Giới thiệu thế để các bạn đỡ nhầm lẫn sau này thôi. =)) Vậy Facade trong Laravel là gì?Facade trong Laravel là gì? Facade có thể dịch đơn giản sang tiếng Việt là bề ngoài, mặt ngoài. Nó cho phép bạn truy cập đến các hàm bên trong các service được khai báo trong Service Container bằng cách gọi các hàm Giải thích như trên thì nghe có vẻ khó hiểu, nhưng thực tế có thể bạn vẫn đang sử dụng Facade nhiều mà không để ý đấy. Hãy cùng xem qua file Nếu để ý ở phần cuối của file config đó, bạn sẽ thấy Laravel đã khai báo sẵn một loạt các class alias, để sau này ta có thể sử dụng trong project của mình dưới cái tên ngắn gọn, thay vì phải viết đầy đủ 0.Tản mạn một chút, nếu bạn thắc mặc tại sao Laravel có thể làm một việc tưởng chừng như "thần thánh" như vậy thì thật ra cũng chả có gì đặc biệt đâu, bởi bản thân PHP đã support cho chúng ta tính năng đó thông qua hàm class_alias rồi. Công việc của bạn bên chỉ là khai báo alias dưới dạng key-value vào trong file 2 sẽ được Laravel thực hiện. Bạn có thể tham khảo class 3 để hiểu rõ bản chất của quá trình này.Quay trở lại vấn đề register alias trong file config, nó có liên qua gì đến chủ đề Facade vậy? Bạn có để ý tên đầy đủ của các class được register alias không? Vâng, chúng đều có 5. Hay nói cách khác các class được register alias ở đây đều là các Facade. Và các Facade mặc định của Laravel đều nằm trong thư mục 6.Ngoài ra, những alias mà bạn có thể hay dùng, chẳng hạn như 7, Auth , 9, 0 ... thì đều là Facade cả đấy.Chẳng hạn như những dòng code quen thuộc sau:
Vâng, việc bạn gọi các hàm 1, hay 2 như trên đều là đang sử dụng Facade. Và hãy nhìn lại phần định nghĩa mà mình viết ở phần đầu nhé. Có đúng là bạn đang sử dụng các hàm static không Tuy nhiên, giờ mới là lúc vấn đề trở nên phức tạp này. Hãy thử vào xem nội dung một file Facade thế nào nhé. Ví dụ như 0
Chỉ có duy nhất 1 method trong class đó, tên là 6, ngoài ra hoàn toàn không có một static method nào khác cả. Vậy thì những hàm 7, 2, hay 9 chui từ đâu ra?Facade hoạt động như thế nào?Giờ ta sẽ tiếp tục tìm hiểu ngọn ngành của một class Facade. Hãy để ý một chút, ta thấy class 1 là 2. Và trong class này ta sẽ thấy có hàm 3
Việc khai báo method với nội dung duy nhất là throw error như thế này thì class kế thừa của bạn bắt buộc phải khai báo override hàm 3 (bằng không sẽ có error). Do đó tất cả các Facade đều sẽ có một static method là 3 (và thật may mắn, Laravel làm hết mọi thứ cho chúng ta, làm tận răng đến mức mỗi Facade chỉ cần có một hàm đó là đủ).Đọc kỹ nội dung abstract class 6 bạn sẽ thấy được rằng nội dung mà method 3 trả về sẽ được sử dụng để tạo ra 8, mà instance này được resolve ra từ Application Instance 9, hay nói cách khác chính là Service Container.Như vậy làm việc với 1 trong Service Container. Việc gọi các hàm static của Auth thực tế sẽ được xử lý trong magic method 4 (bạn có thể tìm hiểu về magic method này ở đây), rồi chuyển qua lời gọi hàm bình thường từ một instance đã được resolve ra từ trong Service Container.Như vậy thì ta có thể thấy các cách gọi sau sẽ là tương đương:
Facade - the Good and the BadFacade có thể nói là một trong những khái niệm hay tính năng gây tranh cãi nhiều nhất của Laravel. Bạn có thể google ra cả đống bài viết, ý kiến cho rằng Facade là một "Bad design", hay "Anti-pattern". Nhưng cũng có nhiều người vẫn yêu thích và sử dụng Facade hàng ngày. Nó đã và vẫn đang là một phần của Laravel."Bad design", hay "Anti-pattern". Nhưng cũng có nhiều người vẫn yêu thích và sử dụng Facade hàng ngày. Nó đã và vẫn đang là một phần của Laravel. Facade thuận tiện. Facade dễ dùng. Facade giúp bạn viết code rất ngắn gọn nhanh chóng. Trên document của Laravel, Facade được miêu tả với rất nhiều ưu điểm như "providing the benefit of a terse, expressive syntax while maintaining more testability and flexibility than traditional static methods". Facade được thiết kế như một cây cầu để người lập trình tiếp cận với "Service" một cách dễ dàng. Bạn có thể sử dụng Facade gần như mọi lúc mọi nơi mà không phải mất công khởi tạo, resolve các instance từ trong Service Container. Facade về bản chất cũng không phải là một class chứa đầy những static method, nên nó không nặng nề chiếm bộ nhớ như những class như vậy. Tuy nhiên chính vì để có được những sự tiện lợi như thế mà ta cần một đống các "phép thuật" được xử lý ngầm "behind the scene". Với một người mới bắt đầu tìm hiểu và sử dụng Laravel, có thể họ sẽ dễ dàng biết đến và sử dụng cách gọi 2, nhưng họ sẽ không thể hiểu được bản chất của hàm đó từ đâu ra. Hay khi gặp vấn đề và cần vào trong code của Framework để kiểm tra thì cũng thật khó để bạn tìm thấy được nguồn gốc của chúng.Hơn thế nữa, với việc quá tiện dụng của Facade, nếu không cẩn thận bạn sẽ có thể làm code trở nên phức tạp và khó đoán biết hơn. Ví dụ như mình muốn kiểm tra một class hoạt động dựa vào các dependencies nào thì mình thường sẽ xem ở trong constructor của nó. Hay trong Laravel có support method injection thì mình cũng xem qua cả trong khai báo method nữa. Thế nhưng, với việc gọi Facade ở bên trong hàm thì ta đã vô hình chung che đi việc hàm, hay class, đó cần một service dependency, thứ mà thay vì ta nên inject vào thì nay được resolve ra thông qua Facade. Lời kếtTrong khuôn khổ nội dung bài viết này, mình xin đứng ngoài cuộc về việc tranh cãi xem nên hay không nên sử dụng Facade. Nó là một tính năng tiện dụng và không phải ngẫu nhiên mà Taylor Otwell, cha đẻ của Laravel, còn giữ lại nó đến ngày hôm nay.nên hay không nên sử dụng Facade. Nó là một tính năng tiện dụng và không phải ngẫu nhiên mà Taylor Otwell, cha đẻ của Laravel, còn giữ lại nó đến ngày hôm nay. Bài viết này chỉ hy vọng có thể giúp các bạn có thể hiểu hơn về những gì xảy ra đằng sau những hàm static mà ta vẫn hay gọi thông qua Facade. Còn với câu hỏi "Nếu không dùng Facade thì có thể dùng cái gì để thay thế?", thì mình xin trả lời là mình vẫn hay dùng Dependency Injection."Nếu không dùng Facade thì có thể dùng cái gì để thay thế?", thì mình xin trả lời là mình vẫn hay dùng Dependency Injection. Hãy dành chút thời gian tham khảo về phần Facade Class Reference trên document của Laravel. Bạn sẽ thấy được bản chất của một Facade là sử dụng instance của class nào, và nếu khi nào có vấn đề gì cần phải xem code của Framework thì cũng biết được nơi nào để mà tìm. Chẳng hạn như để tìm hiểu về các hàm của Facade 6 thì bạn nên tìm đến class 7, với Auth thì là 9 hay static 0 thì là static 1.Và như vậy thì ta có thể thay thế việc sử dụng Facade Có một chú ý ở đây là như mình cũng đã có đề cập ở các bài trước, một class không nên để phụ thuộc vào một class khác mà chỉ nên phụ thuộc vào abstraction (hay interface). Do đó, thay vì typehint
Hy vọng qua bài viết này mọi người có thể hiểu thêm về một tính năng vốn rất quen thuộc của Laravel. Và xin hẹn gặp lại vào bài viết tới, với những đào sâu khác về Framework phổ biến này |