Шаблоны проектирования программного обеспечения лучше всего определены словами Мартина Фаулера :
Шаблоны предоставляют механизм для предоставления рекомендаций по проектированию в справочном формате. Разработка программного обеспечения — это серьезная тема, и, столкнувшись с проблемой проектирования, вы должны сосредоточиться на чем-то настолько близком к проблеме, насколько это возможно.
Код, использующий шаблоны проектирования, легко понять, поддерживать и расширять. Целью данного урока является продвижение фасада в Laravel.
Что такое шаблон фасада?
Согласно определению «Банды четырех», шаблон проектирования фасада является структурным шаблоном, который определяет упрощенный интерфейс к более сложной подсистеме. Шаблон основан на создании простого интерфейса фасада перед набором необходимой логики и методов. Сам фасад поддерживает зависимости.
Фасад очень похож на адаптер и декоратор . Адаптер действует как мост между двумя интерфейсами, которые не совместимы, в то время как декоратор является более сложным и используется для динамического изменения поведения объектов.
Что такое фасады Laravel?
Сладкий синтаксис, который использует Laravel, делает написание кода чище и проще для понимания. Фасады Laravel на самом деле являются синтаксическим сахаром для сервисного расположения .
Давайте посмотрим на фасад Laravel и как он функционирует. Фасад Cache
в Laravel выглядит так:
php Cache::get('key');
Хотя может показаться, что он использует множество статических методов, Laravel фактически предоставляет интерфейс для классов, которые доступны в контейнере службы приложения. Как вы, наверное, уже знаете, написанный выше код эквивалентен:
php $app = app(); $app->make('cache')->get('key');
Фасад Laravel находит объекты в vendor/Laravel/framework/src/Illuminate/Support/Facades
а фасад Cache помещается в Cache.php
:
php namespace Illuminate\Support\Facades; class Cache extends Facade { /** * Get the registered name of the component. * * @return string */ protected static function getFacadeAccessor() { return 'cache'; } }
Когда мы используем cache::get('key')
мы фактически вызываем класс выше. Обязательно создайте псевдоним вышеупомянутого класса в файле config/app.php
:
php 'aliases' => [ //... 'Cache'=>Illuminate\Support\Facades\Cache::class,
Псевдонимы устанавливаются автоматически загрузчиком Laravel. Установка имени класса для кэширования создает согласованность с фасадом. Эта опция наверняка сделает людей, использующих фасады, более комфортными с вашим кодом.
Следующие три метода имеют решающее значение для создания фасада:
- __callStatic () магический метод PHP, который определяется как метод
getFacadeAccessor
в дочернем классе. - Корень фасада, который представляет базовый класс, для которого Фасад вызывает методы.
- Метод
resolveFacadeInstance
отвечает за разрешение правильного экземпляра службы.
Реализация методов фасадного класса:
« `php //… открытая статическая функция __callStatic ($ method, $ args) {$ instance = static :: getFacadeRoot (); switch (count ($ args)) {case 0: return $ instance -> $ method ();
Дело 1: return $ instance -> $ method ($ args [0]); случай 2: return $ instance -> $ method ($ args [0], $ args [1]); случай 3: return $ instance -> $ method ($ args [0], $ args [1], $ args [2]); дело 4: метод возврата $ instance -> $ ($ args [0], $ args [1], $ args [2], $ args [3]); дефолт: return call_user_func_array (массив ($ instance, $ method), $ args); }} `` `
__callStatic
основном вызывает IoC-контейнер для привязки к классу. Он также вызывает свой (нестатический) метод, используя регистр переключателя через call_user_func_array()
PHP call_user_func_array()
, передавая массив параметров в метод getFacadeRoot()
возвращаемого объекта. Метод getFacadeRoot()
показан следующим образом:
php public static function getFacadeRoot() { return static::resolveFacadeInstance( static::getFacadeAccessor() ); }
И resolveFacadeInstance()
:
« `php защищенная статическая функция resolFacadeInstance ($ name) {if (is_object ($ name)) возвращает $ name;
if (isset (static :: $ resolvedInstance [$ name])) { return static :: $ resolvedInstance [$ name]; } вернуть static :: $ resolvedInstance [$ name] = static :: $ app [$ name]; } `` `
Как resolveFacadeInstance
в последней строке статьи, в методе resolveFacadeInstance
Laravel возвращает экземпляр локатора службы. Поскольку локатор является чистым экземпляром исходного класса, мы заключаем, что фасад Laravel не совпадает с определением шаблона фасада GoF. Это только места обслуживания. В отличие от фасада Laravel, Real Facade делает написание юнит-тестов трудным, а иногда даже невозможным из-за создания жестко закодированных зависимостей.
Для тех, кто считает, что DI через конструктор является лучшим вариантом, чем использование фасада Laravel, я хотел бы сообщить вам, что некоторые дополнительные конфигурации могут быть включены.
Как создать фасад Laravel
Я хочу создать контрольный файл Laravel Facade, который отвечает за проверку, является ли входной файл PDF или нет. Для этого прежде всего нам нужно создать класс Is Pdf
в App/MyFacade/IsPdf.php
:
« `php namespace App \ MyFacade;
class IsPdf {private $ pdf = «\ x25 \ x50 \ x44 \ x46 \ x2D»;
проверка публичной функции ($ file) { return (file_get_contents ($ file, false, null, 0, strlen ($ this-> pdf)) === $ this-> pdf)? правда: ложь; }} `` `
Во-вторых, свяжите класс с поставщиком услуг. Вы создадите нового поставщика услуг, который будет расположен в App\Providers\IsPdfServiceProvider:
« `php namespace App \ Providers;
используйте Освещение \ Поддержка \ Фасады \ Приложение; использовать Illuminate \ Support \ ServiceProvider;
Класс IsPdfServiceProvider расширяет ServiceProvider {/ ** * Загрузка служб приложений. * * @return void * / public function boot () {//}
/ ** * Зарегистрируйте приложение услуг. * * @turn void * / регистр публичной функции () { App :: bind ('IsPdf', функция () { вернуть новый \ App \ MyFacade \ IsPdf; }); }}
« `
В-третьих, создайте класс Facade как расширение ранее упомянутого класса Illuminate\Support\Facades\Facade
. Вы создадите класс, который будет расположен в App\Facades\IsPdfFacade.php
.
« `php namespace App \ Facades; используйте Освещение \ Поддержка \ Фасады \ Фасад;
класс IsPdf расширяет Facade {защищенная статическая функция getFacadeAccessor () {return ‘IsPdf’; }} « `Последний шаг — зарегистрировать Фасад в config/app.php:
« `php / * * Поставщики сервисов приложений… * / App \ Providers \ IsPdfServiceProvider :: class,
« `
И псевдоним:
php 'IsPdf' => App\Facades\IsPdf::class
Поздравляем! Вы успешно создали фасад Laravel. Не стесняйтесь тестировать Фасад, используя некоторые коды, такие как:
php Route::get('/', function(){ IsPdf::check('/files/file.pdf'); });
Вывод
Теперь мы знаем, что фасад Laravel упрощает вызов методов, и внедрение фактических зависимостей может действительно окупиться. Конечно, у Laravel Facade есть свои преимущества и недостатки. Это зависит от разработчика, чтобы выбрать правильный вариант.
Для дополнительных ресурсов с участием Laravel, обязательно ознакомьтесь с предложением на рынке .
Кто знает, может быть, эта статья поможет вам разработать независимый от фреймворка код и забыть об использовании фасадов! Удачи!