статья: https://laravel.ru/docs/v5/contracts Цитирую (мои комментарии курсивом): Но для начала рассмотрим код с сильной связностью с реализацией кэша. Рассмотрите следующее: Код (PHP): <?php namespace App\Orders; class Repository { /** * Кеш. */ protected $cache; /** * Создание нового экземпляра репозитория. * * @param \SomePackage\Cache\Memcached $cache * @return void */ public function __construct(\SomePackage\Cache\Memcached $cache) { $this->cache = $cache; } /** * Получение заказа по ID. * * @param int $id * @return Order */ public function find($id) { if ($this->cache->has($id)) { // } } } В этом классе код сильно связан с реализацией кэша, потому что мы зависим от конкретного класса Cache данного пакета. Если API этого пакета изменится, наш код должен также измениться. Аналогично, если мы хотим заменить нашу базовую технологию кэша (Memcached) другой технологией (Redis), нам придётся вносить изменения в наш репозиторий. (моё прим. - здесь пока всё ясно, я со всем согласен) Вместо такого подхода, мы можем улучшить наш код, добавив зависимость от простого интерфейса, которой не зависит от поставщика: (моё прим. - те предлагают создать собственный интерфейс) Код (PHP): <?php namespace App\Orders; //Contracts - это так в ларавель называются интерфейсы use Illuminate\Contracts\Cache\Repository as Cache; class Repository { /** * Создание нового экземпляра репозитория. * * @param Cache $cache * @return void */ public function __construct(Cache $cache) { $this->cache = $cache; } } Теперь код не привязан к какому-либо определённому поставщику, и даже не привязан к Laravel. Контракт не содержит никакой конкретной реализации и никаких зависимостей. Вы можете легко написать свою реализацию любого контракта, что позволяет вам заменить реализацию работы с кэшем, не изменяя ни одной строчки вашего кода, работающего с кэшем. Я правильно понял что они предлагают просто написать свою обёртку поверх, подключаемой библиотеки. Которая будет реализацией, интерфейса, который мы используем в конструкторе при внедрении. И получается если апи библиотеки изменится, или мы вообще заменим библиотеку , то соответственно придётся переписывать нашу обёртку. Тут я даже не знаю что проще - переписывать обёртку(реализация нашего интерфейса), или лезть править в вызывающий код. Преимущества интерфейсов вообще не понятны, во делов то поменять уточнение класса, там где он внедряется.
нет. Просто тут в примере говорится об интерфейсах, а в примере нет примера интерфейса. Так вот жизнь повернулась. Интерфейс, контракт или ченить из это оперы это когда ты вроде как объявляешь класс, в котором описаны методы и их параметры, но самого кода нет. Чтобы не делать такие классы-пустышки для того, чтобы людям было понятно и чтобы IDE подсказывала и проверяла, то вот придумали "интерфейсы". вот тут первый пример всё понятно http://php.ru/manual/language.oop5.interfaces.html Код (PHP): // Объявим интерфейс 'iTemplate' interface iTemplate { public function setVariable($name, $var); public function getHtml($template); } Добавлено спустя 3 минуты 32 секунды: преимущества интерфейсов в том, что их IDE цепляет. Я сделал cms, сделал в ней кеш на файлах, кеш на мемкеше. Зарелизил. Потом прошло три года, я охладел, вышел редис, и чел, который пилит сайт на моей cms хочет сделать на редисе. И в этот момент ему не нужно смотреть примеры моих классов кеширующих. Ему нужды только методы и их параметры. Всё. Он смотрит на интерфейс и кодит свой кешер редисковый. Когда у тебя таких ситуаций вагон, когда к твоим методам кто-то другой пилит что-то совместимое, тогда интерфейсы как способ проверить наличие ожидаемых методов и их параметров весьма удобны.
Там в примере во втором коде интерфейс используют в конструкторе. Подразумевается что те кто читают эту статью, знают что такое интерфейс в PHP ну или в других ЯПах. Поэтому там не объясняется что это такое.
а тема статьи тогда в чем? Если в статье подразумевается, что читатель знает, что это, то зачем вообще об этом говорить? Чушь какая-то.
Тема статьи о контрактах ларки. К примеру хочешь ты замутить свой валидатор вместо нативного, берешь контракт в виде интерфейса или набора интерфейсов, реализуешь, регистрируешь, пользуешь его как нативный. То что кусок террориста воспринял это как документацию по интерфейсам - проблемы куска террориста )
он не воспринял. Окей. Я понял. Эта статья о том, что ларка поддерживает и имеет в себе интерфейсы для удобства велосипедостроителей и кастома. Окей. Я всё понял.
Цитата о том, что не нужно делать зависимость от реализации, нужно делать зависимость от интерфейса. Интерфейс нам говорит как о том, какие методы мы можем использовать... так и о том, какие методы нужно написать в реализации. Это не обертка, это правильнее назвать - документацией или спецификацией. Interface в языке PHP - это механизм документирования интерфейса с проверками на стороне движка языка на соответствие. Т.е. ты пишешь спецификацию, которой должен следовать класс, что бы работать с твоим. "Уточнение класса" то поменять не сложно, но можно облажаться, забыв реализовать какой-нибудь метод. Ну и, второе, о чем речь - о внедрении зависимостей. Плохо, если мы связываем класс с каким-то другим. Мы же можем захотеть использовать разные классы - в разных проектах, в разных условиях. Для разработки - один класс, для продакшена - другой, для тестирования - третий. Вот мы и говорим, что не нужен нам конкретный класс, а нужен класс реализующий вот такой вот контракт (реализующий интерфейс). А какой конкретно класс будет передан в конструктор нашему классу - уже настраивается в другом месте, чуть ли не в конфиге приложения.
А разве это не вытекает из самой задумки интерфейсов, и люди которые знают, что такое интерфейсы, они это все само собой понимают?
Ну так знать термин и знать - как это применять - две разные вещи. Многие до сих пор не различают интерфейс объекта и способы его описания (interface в PHP) и с умным видом говорят, что в других языках может не быть интерфейса у объектов. А ты про "само собой"