За последние 24 часа нас посетил 23181 программист и 1516 роботов. Сейчас ищут 859 программистов ...

Интерфейсы и слабая связность

Тема в разделе "PHP для новичков", создана пользователем machetero, 24 фев 2016.

  1. machetero

    machetero Активный пользователь

    С нами с:
    25 окт 2014
    Сообщения:
    499
    Симпатии:
    21
    статья: https://laravel.ru/docs/v5/contracts
    Цитирую (мои комментарии курсивом):

    Но для начала рассмотрим код с сильной связностью с реализацией кэша. Рассмотрите следующее:
    Код (PHP):
    1. <?php namespace App\Orders;
    2.  
    3. class Repository {
    4.  
    5.   /**
    6.    * Кеш.
    7.    */
    8.   protected $cache;
    9.  
    10.   /**
    11.    * Создание нового экземпляра репозитория.
    12.    *
    13.    * @param  \SomePackage\Cache\Memcached  $cache
    14.    * @return void
    15.    */
    16.   public function __construct(\SomePackage\Cache\Memcached $cache)
    17.   {
    18.     $this->cache = $cache;
    19.   }
    20.  
    21.   /**
    22.    * Получение заказа по ID.
    23.    *
    24.    * @param  int  $id
    25.    * @return Order
    26.    */
    27.   public function find($id)
    28.   {
    29.     if ($this->cache->has($id))
    30.     {
    31.       //
    32.     }
    33.   }
    34.  
    35. } 
    В этом классе код сильно связан с реализацией кэша, потому что мы зависим от конкретного класса Cache данного пакета. Если API этого пакета изменится, наш код должен также измениться.
    Аналогично, если мы хотим заменить нашу базовую технологию кэша (Memcached) другой технологией (Redis), нам придётся вносить изменения в наш репозиторий.
    (моё прим. - здесь пока всё ясно, я со всем согласен)
    Вместо такого подхода, мы можем улучшить наш код, добавив зависимость от простого интерфейса, которой не зависит от поставщика:
    (моё прим. - те предлагают создать собственный интерфейс)
    Код (PHP):
    1. <?php namespace App\Orders;
    2.  
    3. //Contracts - это так в ларавель называются интерфейсы
    4.  
    5. use Illuminate\Contracts\Cache\Repository as Cache; 
    6.  
    7. class Repository {
    8.  
    9.   /**
    10.    * Создание нового экземпляра репозитория.
    11.    *
    12.    * @param  Cache  $cache
    13.    * @return void
    14.    */
    15.   public function __construct(Cache $cache)
    16.   {
    17.     $this->cache = $cache;
    18.   }
    19.  
    20. } 
    Теперь код не привязан к какому-либо определённому поставщику, и даже не привязан к Laravel. Контракт не содержит никакой конкретной реализации и никаких зависимостей. Вы можете легко написать свою реализацию любого контракта, что позволяет вам заменить реализацию работы с кэшем, не изменяя ни одной строчки вашего кода, работающего с кэшем.

    Я правильно понял что они предлагают просто написать свою обёртку поверх, подключаемой библиотеки. Которая будет реализацией, интерфейса, который мы используем в конструкторе при внедрении. И получается если апи библиотеки изменится, или мы вообще заменим библиотеку , то соответственно придётся переписывать нашу обёртку. Тут я даже не знаю что проще - переписывать обёртку(реализация нашего интерфейса), или лезть править в вызывающий код. Преимущества интерфейсов вообще не понятны, во делов то поменять уточнение класса, там где он внедряется.
     
  2. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    нет. Просто тут в примере говорится об интерфейсах, а в примере нет примера интерфейса. Так вот жизнь повернулась.

    Интерфейс, контракт или ченить из это оперы это когда ты вроде как объявляешь класс, в котором описаны методы и их параметры, но самого кода нет. Чтобы не делать такие классы-пустышки для того, чтобы людям было понятно и чтобы IDE подсказывала и проверяла, то вот придумали "интерфейсы".

    вот тут первый пример всё понятно http://php.ru/manual/language.oop5.interfaces.html

    Код (PHP):
    1. // Объявим интерфейс 'iTemplate'
    2. interface iTemplate
    3. {
    4.     public function setVariable($name, $var);
    5.     public function getHtml($template);
    6. }
    Добавлено спустя 3 минуты 32 секунды:
    преимущества интерфейсов в том, что их IDE цепляет. Я сделал cms, сделал в ней кеш на файлах, кеш на мемкеше. Зарелизил. Потом прошло три года, я охладел, вышел редис, и чел, который пилит сайт на моей cms хочет сделать на редисе. И в этот момент ему не нужно смотреть примеры моих классов кеширующих. Ему нужды только методы и их параметры. Всё. Он смотрит на интерфейс и кодит свой кешер редисковый.

    Когда у тебя таких ситуаций вагон, когда к твоим методам кто-то другой пилит что-то совместимое, тогда интерфейсы как способ проверить наличие ожидаемых методов и их параметров весьма удобны.
     
  3. machetero

    machetero Активный пользователь

    С нами с:
    25 окт 2014
    Сообщения:
    499
    Симпатии:
    21
    Там в примере во втором коде интерфейс используют в конструкторе. Подразумевается что те кто читают эту статью, знают что такое интерфейс в PHP ну или в других ЯПах. Поэтому там не объясняется что это такое.
     
  4. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    а тема статьи тогда в чем? Если в статье подразумевается, что читатель знает, что это, то зачем вообще об этом говорить? Чушь какая-то.
     
  5. romach

    romach Старожил

    С нами с:
    26 окт 2013
    Сообщения:
    2.904
    Симпатии:
    719
    Тема статьи о контрактах ларки. К примеру хочешь ты замутить свой валидатор вместо нативного, берешь контракт в виде интерфейса или набора интерфейсов, реализуешь, регистрируешь, пользуешь его как нативный. То что кусок террориста воспринял это как документацию по интерфейсам - проблемы куска террориста )
     
  6. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    он не воспринял. Окей. Я понял. Эта статья о том, что ларка поддерживает и имеет в себе интерфейсы для удобства велосипедостроителей и кастома. Окей. Я всё понял.
     
  7. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
    Цитата о том, что не нужно делать зависимость от реализации, нужно делать зависимость от интерфейса. Интерфейс нам говорит как о том, какие методы мы можем использовать... так и о том, какие методы нужно написать в реализации.

    Это не обертка, это правильнее назвать - документацией или спецификацией. Interface в языке PHP - это механизм документирования интерфейса с проверками на стороне движка языка на соответствие. Т.е. ты пишешь спецификацию, которой должен следовать класс, что бы работать с твоим. "Уточнение класса" то поменять не сложно, но можно облажаться, забыв реализовать какой-нибудь метод.

    Ну и, второе, о чем речь - о внедрении зависимостей. Плохо, если мы связываем класс с каким-то другим. Мы же можем захотеть использовать разные классы - в разных проектах, в разных условиях. Для разработки - один класс, для продакшена - другой, для тестирования - третий. Вот мы и говорим, что не нужен нам конкретный класс, а нужен класс реализующий вот такой вот контракт (реализующий интерфейс). А какой конкретно класс будет передан в конструктор нашему классу - уже настраивается в другом месте, чуть ли не в конфиге приложения.
     
  8. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    А разве это не вытекает из самой задумки интерфейсов, и люди которые знают, что такое интерфейсы, они это все само собой понимают?
     
  9. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
    Ну так знать термин и знать - как это применять - две разные вещи. Многие до сих пор не различают интерфейс объекта и способы его описания (interface в PHP) и с умным видом говорят, что в других языках может не быть интерфейса у объектов. А ты про "само собой" ;)
     
  10. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    ясненько