{{TOC}} {{DOCVER 5.3=c06d6a2352ed8c767633aab9c20f2bf7d880c967 28.01.2017 5:00:51, 5.2=6b0b057ae6de3c88cb29188459e38383c622ec23 8.12.2016 23:00:15, 5.1=cdc24ba7426c5b11eb4d050706bd78c3ea4913cc 19.06.2016 20:08:01, 5.0=5d10040a981deee82c0fde0e8e5d2ffc49eaaecb 8.02.2016 18:09:11}} == Введение == Контракты в Laravel - это набор интерфейсов, которые описывают основной функционал, предоставляемый фреймворком. Например, контракт %%(t)Illuminate\Contracts\Queue\Queue%% определяет методы, необходимые для организации очередей, в то время как контракт %%(t)Illuminate\Contracts\Mail\Mailer%% определяет методы, необходимые для отправки электронной почты. Каждый контракт имеет свою реализацию во фреймворке. Например, Laravel предоставляет реализацию %%Queue%% с различными драйверами и реализацию %%Mailer%%, использующую ((http://swiftmailer.org/ SwiftMailer)). Все контракты Laravel живут в ((https://github.com/illuminate/contracts своих собственных репозиториях GitHub)). Эта ссылка ведёт на все доступные контракты, а также на один отдельный пакет, который может быть использован разработчиками пакетов. === Контракты или фасады? === ((/docs/v5/facades Фасады)) Laravel и вспомогательные функции дают простой способ использования сервисов Laravel без необходимости типизирования и извлечения контрактов из сервис-контейнера. В большинстве случаев у каждого фасада есть эквивалентный контракт. В отличие от фасадов, которые не требуют того, чтобы вы запрашивали их в конструкторе вашего класса, контракты позволяют вам определить конкретные зависимости для ваших классов. Некоторые разработчики предпочитают именно так явно определять свои зависимости, поэтому предпочитают использовать контракты, а другие разработчики наслаждаются удобством фасадов. .(alert) Для большинства приложений неважно, что вы выберете - фасады или контракты. Но если вы создаёте пакет, то вам надо использовать контракты, так как в этом случае их проще тестировать. == Когда использовать контракты == Это обсуждается повсюду, и большинство дискуссий сводятся к тому, что использование контрактов или фасадов - это дело вкуса или предпочтений вашей команды разработчиков. И те, и другие можно использовать для создания надёжных, проверенных Laravel-приложений. Пока вы сохраняете границы ответственности вашего класса узкими, вы сможете заметить всего несколько практических различий между использованием контрактов и фасадов. Однако, у вас по-прежнему могут остаться некоторые вопросы о контрактах. Например, зачем вообще нужны интерфейсы? Разве их использование делает жизнь проще? Определим причины использования интерфейсов как следующие: это слабая связанность (loose coupling) и упрощение кода. === Слабая связанность === Но для начала рассмотрим код с сильной связанностью с реализацией кэша. Рассмотрите следующее: %% cache = $cache; } /** * Получение заказа по ID. * * @param int $id * @return Order */ public function find($id) { if ($this->cache->has($id)) { // } } } %% В этом классе код сильно связан с реализацией кэша, потому что мы зависим от конкретного класса Cache данного пакета. Если API этого пакета изменится, наш код должен также измениться. Аналогично, если мы хотим заменить нашу базовую технологию кэша (Memcached) другой технологией (Redis), нам придётся вносить изменения в наш репозиторий. А наш репозиторий не должен задумываться о том, кто именно предоставляет данные или как он это делает. **Вместо такого подхода, мы можем улучшить наш код, добавив зависимость от простого интерфейса, которой не зависит от поставщика:** %% cache = $cache; } } %% Теперь код не привязан к какому-либо определённому поставщику, и даже не привязан к Laravel. Контракт не содержит никакой конкретной реализации и никаких зависимостей. Вы можете легко написать свою реализацию любого контракта, что позволяет вам заменить реализацию работы с кэшем, не изменяя ни одной строчки вашего кода, работающего с кэшем. === Упрощение кода === Когда все сервисы Laravel аккуратно определены в простых интерфейсах, очень легко определить функциональность, предлагаемую данными сервисами. **Фактически, контракты являются краткой документацией для функций Laravel.** Кроме того, когда в своём приложении вы внедряете в классы зависимости от простых интерфейсов, в вашем коде легче разобраться и его проще поддерживать. Вместо того, чтобы искать методы в большом и сложном классе, вы можете обратиться к простому и понятному интерфейсу. == Как использовать контракты == Как получить реализацию контракта? Это довольно просто. Множество типов классов в Laravel регистрируются в ((/docs/v5/container сервис-контейнере)), включая контроллеры, слушатели событий, посредники, очереди и даже замыкания. Поэтому, чтобы получить реализацию контракта, вам достаточно указать тип интерфейса в конструкторе необходимого класса. Например, посмотрите на этот обработчик событий: %% redis = $redis; } /** * Обработка события. * * @param OrderWasPlaced $event * @return void */ public function handle(OrderWasPlaced $event) { // } } %% Когда будет получен слушатель события, сервис-контейнер прочитает указание типа в конструкторе класса и внедрит нужное значение. Узнать больше о регистрации в сервис-контейнере можно в ((/docs/v5/container документации)). == Список контрактов == В этой таблице приведены ссылки на все контракты Laravel, а также эквивалентные им фасады: %%(hvlraw)
Контракт Соответствующий фасад
Illuminate\Contracts\Auth\Factory для 5.2+
Illuminate\Contracts\Auth\Guard для 5.1-
Auth
Illuminate\Contracts\Auth\PasswordBrokerPassword
Illuminate\Contracts\Bus\DispatcherBus
Illuminate\Contracts\Broadcasting\Broadcaster 
Illuminate\Contracts\Cache\RepositoryCache
Illuminate\Contracts\Cache\FactoryCache::driver()
Illuminate\Contracts\Config\RepositoryConfig
Illuminate\Contracts\Container\ContainerApp
Illuminate\Contracts\Cookie\FactoryCookie
Illuminate\Contracts\Cookie\QueueingFactoryCookie::queue()
Illuminate\Contracts\Encryption\EncrypterCrypt
Illuminate\Contracts\Events\DispatcherEvent
Illuminate\Contracts\Filesystem\Cloud 
Illuminate\Contracts\Filesystem\FactoryFile
Illuminate\Contracts\Filesystem\FilesystemFile
Illuminate\Contracts\Foundation\ApplicationApp
Illuminate\Contracts\Hashing\HasherHash
Illuminate\Contracts\Logging\LogLog
Illuminate\Contracts\Mail\MailQueueMail::queue()
Illuminate\Contracts\Mail\MailerMail
Illuminate\Contracts\Queue\FactoryQueue::driver()
Illuminate\Contracts\Queue\QueueQueue
Illuminate\Contracts\Redis\DatabaseRedis
Illuminate\Contracts\Routing\RegistrarRoute
Illuminate\Contracts\Routing\ResponseFactoryResponse
Illuminate\Contracts\Routing\UrlGeneratorURL
Illuminate\Contracts\Support\Arrayable 
Illuminate\Contracts\Support\Jsonable 
Illuminate\Contracts\Support\Renderable 
Illuminate\Contracts\Validation\FactoryValidator::make()
Illuminate\Contracts\Validation\Validator 
Illuminate\Contracts\View\FactoryView::make()
Illuminate\Contracts\View\View 
%%