Вступление
Контракты Laravel - это набор интерфейсов, которые определяют основные сервисы, предоставляемые платформой. Например, контракт определяет методы, необходимые для постановки в очередь, а контракт определяет методы, необходимые для отправки электронной почты.Illuminate\Contracts\Queue\Queue
Illuminate\Contracts\Mail\Mailer
Каждый контракт имеет соответствующую реализацию, предусмотренную рамками. Например, Laravel предоставляет реализацию очереди с различными драйверами и реализацию почтовой программы, основанную на SwiftMailer .
Все контракты Laravel живут в своем собственном репозитории GitHub . Это обеспечивает быструю контрольную точку для всех доступных контрактов, а также отдельный, отсоединенный пакет, который может использоваться разработчиками пакетов.
Контракты Vs. Фасады
Фасады и вспомогательные функции Laravel предоставляют простой способ использования сервисов Laravel без необходимости указывать подсказки и разрешать контракты из сервисного контейнера. В большинстве случаев каждый фасад имеет эквивалентный контракт.
В отличие от фасадов, которые не требуют от вас их использования в конструкторе вашего класса, контракты позволяют вам определять явные зависимости для ваших классов. Некоторые разработчики предпочитают явно определять свои зависимости таким образом и поэтому предпочитают использовать контракты, в то время как другие разработчики пользуются удобством фасадов.
Большинство приложений подойдет независимо от того, предпочитаете ли вы фасады или контракты. Однако, если вы создаете пакет, вам следует рассмотреть возможность использования контрактов, поскольку их будет проще тестировать в контексте пакета.
Когда использовать контракты
Как уже говорилось в другом месте, большая часть решения об использовании контрактов или фасадов будет зависеть от личного вкуса и вкусов вашей команды разработчиков. И контракты, и фасады могут быть использованы для создания надежных, хорошо протестированных приложений Laravel. Пока вы сосредоточены на обязанностях своего класса, вы заметите очень мало практических различий между использованием контрактов и фасадов.
Тем не менее, у вас все еще может быть несколько вопросов относительно контрактов. Например, зачем вообще использовать интерфейсы? Разве использование интерфейсов не сложнее? Давайте рассмотрим причины использования интерфейсов для следующих заголовков: слабая связь и простота.
Слабая связь
Сначала давайте рассмотрим некоторый код, тесно связанный с реализацией кеша. Учтите следующее:
<?php
namespace App\Orders;
class Repository
{
/**
* The cache instance.
*/
protected $cache;
/**
* Create a new repository instance.
*
* @param \SomePackage\Cache\Memcached $cache
* @return void
*/
public function __construct(\SomePackage\Cache\Memcached $cache)
{
$this->cache = $cache;
}
/**
* Retrieve an Order by ID.
*
* @param int $id
* @return Order
*/
public function find($id)
{
if ($this->cache->has($id)) {
//
}
}
}
В этом классе код тесно связан с данной реализацией кеша. Он тесно связан, потому что мы зависим от конкретного класса Cache от поставщика пакетов. Если API этого пакета изменится, наш код также должен измениться.
Аналогично, если мы хотим заменить нашу базовую технологию кэширования (Memcached) другой технологией (Redis), нам снова придется модифицировать наш репозиторий. В нашем хранилище не должно быть много знаний о том, кто предоставляет им данные или как они их предоставляют.
Вместо этого мы можем улучшить наш код, полагаясь на простой, независимый от поставщика интерфейс:
<?php
namespace App\Orders;
use Illuminate\Contracts\Cache\Repository as Cache;
class Repository
{
/**
* The cache instance.
*/
protected $cache;
/**
* Create a new repository instance.
*
* @param Cache $cache
* @return void
*/
public function __construct(Cache $cache)
{
$this->cache = $cache;
}
}
Теперь код не связан с каким-либо конкретным поставщиком или даже Laravel. Поскольку пакет контрактов не содержит реализацию и никаких зависимостей, вы можете легко написать альтернативную реализацию любого данного контракта, позволяющую заменить реализацию кеша без изменения какого-либо кода, потребляющего кеш.
Простота
Когда все сервисы Laravel четко определены в простых интерфейсах, очень легко определить функциональность, предлагаемую данным сервисом. Контракты служат краткой документацией к особенностям платформы.
Кроме того, когда вы зависите от простых интерфейсов, ваш код легче понять и поддерживать. Вместо того, чтобы отслеживать, какие методы доступны вам в большом, сложном классе, вы можете обратиться к простому, понятному интерфейсу.
Как использовать контракты
Итак, как вы получаете реализацию контракта? Это на самом деле довольно просто.
Многие типы классов в Laravel разрешаются через контейнер служб , включая контроллеры, прослушиватели событий, промежуточное программное обеспечение, задания в очереди и даже замыкания маршрутов. Таким образом, чтобы получить реализацию контракта, вы можете просто «напечатать подсказку» интерфейса в конструкторе разрешаемого класса.
Например, взгляните на слушателя этого события:
<?php
namespace App\Listeners;
use App\User;
use App\Events\OrderWasPlaced;
use Illuminate\Contracts\Redis\Factory;
class CacheOrderInformation
{
/**
* The Redis factory implementation.
*/
protected $redis;
/**
* Create a new event handler instance.
*
* @param Factory $redis
* @return void
*/
public function __construct(Factory $redis)
{
$this->redis = $redis;
}
/**
* Handle the event.
*
* @param OrderWasPlaced $event
* @return void
*/
public function handle(OrderWasPlaced $event)
{
//
}
}
Когда обработчик событий разрешен, сервисный контейнер будет читать подсказки типов в конструкторе класса и вставлять соответствующее значение. Чтобы узнать больше о регистрации вещей в сервисном контейнере, ознакомьтесь с его документацией .
Ссылка на контракт
В этой таблице приведены краткие ссылки на все контракты Laravel и их эквивалентные фасады:
Contract | References Facade |
---|---|
Illuminate\Contracts\Auth\Access\Authorizable | |
Illuminate\Contracts\Auth\Access\Gate | Gate |
Illuminate\Contracts\Auth\Authenticatable | |
Illuminate\Contracts\Auth\CanResetPassword | |
Illuminate\Contracts\Auth\Factory | Auth |
Illuminate\Contracts\Auth\Guard | Auth::guard() |
Illuminate\Contracts\Auth\PasswordBroker | Password::broker() |
Illuminate\Contracts\Auth\PasswordBrokerFactory | Password |
Illuminate\Contracts\Auth\StatefulGuard | |
Illuminate\Contracts\Auth\SupportsBasicAuth | |
Illuminate\Contracts\Auth\UserProvider | |
Illuminate\Contracts\Bus\Dispatcher | Bus |
Illuminate\Contracts\Bus\QueueingDispatcher | Bus::dispatchToQueue() |
Illuminate\Contracts\Broadcasting\Factory | Broadcast |
Illuminate\Contracts\Broadcasting\Broadcaster | Broadcast::connection() |
Illuminate\Contracts\Broadcasting\ShouldBroadcast | |
Illuminate\Contracts\Broadcasting\ShouldBroadcastNow | |
Illuminate\Contracts\Cache\Factory | Cache |
Illuminate\Contracts\Cache\Lock | |
Illuminate\Contracts\Cache\LockProvider | |
Illuminate\Contracts\Cache\Repository | Cache::driver() |
Illuminate\Contracts\Cache\Store | |
Illuminate\Contracts\Config\Repository | Config |
Illuminate\Contracts\Console\Application | |
Illuminate\Contracts\Console\Kernel | Artisan |
Illuminate\Contracts\Container\Container | App |
Illuminate\Contracts\Cookie\Factory | Cookie |
Illuminate\Contracts\Cookie\QueueingFactory | Cookie::queue() |
Illuminate\Contracts\Database\ModelIdentifier | |
Illuminate\Contracts\Debug\ExceptionHandler | |
Illuminate\Contracts\Encryption\Encrypter | Crypt |
Illuminate\Contracts\Events\Dispatcher | Event |
Illuminate\Contracts\Filesystem\Cloud | Storage::cloud() |
Illuminate\Contracts\Filesystem\Factory | Storage |
Illuminate\Contracts\Filesystem\Filesystem | Storage::disk() |
Illuminate\Contracts\Foundation\Application | App |
Illuminate\Contracts\Hashing\Hasher | Hash |
Illuminate\Contracts\Http\Kernel | |
Illuminate\Contracts\Mail\MailQueue | Mail::queue() |
Illuminate\Contracts\Mail\Mailable | |
Illuminate\Contracts\Mail\Mailer | Mail |
Illuminate\Contracts\Notifications\Dispatcher | Notification |
Illuminate\Contracts\Notifications\Factory | Notification |
Illuminate\Contracts\Pagination\LengthAwarePaginator | |
Illuminate\Contracts\Pagination\Paginator | |
Illuminate\Contracts\Pipeline\Hub | |
Illuminate\Contracts\Pipeline\Pipeline | |
Illuminate\Contracts\Queue\EntityResolver | |
Illuminate\Contracts\Queue\Factory | Queue |
Illuminate\Contracts\Queue\Job | |
Illuminate\Contracts\Queue\Monitor | Queue |
Illuminate\Contracts\Queue\Queue | Queue::connection() |
Illuminate\Contracts\Queue\QueueableCollection | |
Illuminate\Contracts\Queue\QueueableEntity | |
Illuminate\Contracts\Queue\ShouldQueue | |
Illuminate\Contracts\Redis\Factory | Redis |
Illuminate\Contracts\Routing\BindingRegistrar | Route |
Illuminate\Contracts\Routing\Registrar | Route |
Illuminate\Contracts\Routing\ResponseFactory | Response |
Illuminate\Contracts\Routing\UrlGenerator | URL |
Illuminate\Contracts\Routing\UrlRoutable | |
Illuminate\Contracts\Session\Session | Session::driver() |
Illuminate\Contracts\Support\Arrayable | |
Illuminate\Contracts\Support\Htmlable | |
Illuminate\Contracts\Support\Jsonable | |
Illuminate\Contracts\Support\MessageBag | |
Illuminate\Contracts\Support\MessageProvider | |
Illuminate\Contracts\Support\Renderable | |
Illuminate\Contracts\Support\Responsable | |
Illuminate\Contracts\Translation\Loader | |
Illuminate\Contracts\Translation\Translator | Lang |
Illuminate\Contracts\Validation\Factory | Validator |
Illuminate\Contracts\Validation\ImplicitRule | |
Illuminate\Contracts\Validation\Rule | |
Illuminate\Contracts\Validation\ValidatesWhenResolved | |
Illuminate\Contracts\Validation\Validator | Validator::make() |
Illuminate\Contracts\View\Engine | |
Illuminate\Contracts\View\Factory | View |
Illuminate\Contracts\View\View | View::make() |
0 комментариев