<MyRusakov.ru />

PHP и MySQL с Нуля до Гуру 2.0

PHP и MySQL с Нуля до Гуру 2.0

Данный курс научит Вас программировать на самом популярном Web-языке в мире - PHP. Курс состоит из 11 разделов, в которых с нуля рассказывается и показывается процесс написания различных скриптов на PHP.

В курсе Вы узнаете всю необходимую теоретическую часть, а также увидите массу практических примеров, в том числе, и из моей практики.

Почти к каждому уроку идут упражнения.

Просмотрев данный курс, Вы сможете создавать абсолютно любые PHP-сайты любой сложности.

Подробнее
Подписка

Подписавшись по E-mail, Вы будете получать уведомления о новых статьях.

Подписка Подписаться

Добавляйтесь ко мне в друзья ВКонтакте! Отзывы о сайте и обо мне оставляйте в моей группе.

Мой аккаунт Мой аккаунт Моя группа
Опрос

Каким движком Вы предпочитаете пользоваться?

Что такое внедрение зависимостей в PHP

Что такое внедрение зависимостей в PHP

Разработка любого, мало-мальски сложного, Web-приложения редко когда обходиться без использования сторонних компонентов и библиотек. При этом возникает вопрос - как управлять зависимостями приложения? Управление зависимостями в PHP является одной из важнейших и сложнейших задач при написании Web-приложений. Оно используется для грамотной организации процесса разработки, избавляя программиста от большого числа рутинных задач.

При написании приложения, как правило, используется множество разнообразных PHP классов и один класс может вызывать методы одного или нескольких других классов. Поэтому мы говорим, что данный класс зависит от других классов. Например:

<?php

  // класс телефона
  class Phone
  {
   // делает звонок
   public function makeCall() {
    // используя встроенный передатчик
    $radio = new RadioSignaler();
    $radio -> connect();
   }
  }

?>

Здесь класс Phone зависит от класса RadioSignaler, и, если по какой-то причине класс RadioSignaler окажется недоступен, то данный код работать не будет. Более того, всякий раз, когда создание экземпляра одного класса прописывается в другом классе, то создается жесткая зависимость от данного класса, что делает крайне сложным написание тестируемого и легкого в сопровождении кода.

Перед тем как двигаться дальше, давайте рассмотрим более реалистичный пример. Как-то я уже писал как создать социальную сеть, а в социальных сетях крайне популярно обмениваться контентом (новости, фото, видео). Так вот, представьте, что у нас есть класс под названием SocialFeeds, который собирает новости из различных источников, таких как ВКонтакте, Twitter, Facebook и т. д. Для каждого из этих источников есть свой отдельный класс сервиса. Мы рассмотрим класс TwitterService.

Класс SocialFeeds отправляет запрос на Twitter при помощи класса TwitterService. Этот класс, в свою очередь, извлекает из базы данных специальный токен (ключ) пользователя для доступа к API Twitter. Токен передается классу OAuth, который, используя полученый ключ, запрашивает новости из Twitter и возвращает их обратно в класс SocialFeeds.

<?php

  class SocialFeeds
  {
   // получает новости из Twitter и печатает их
   public function getSocialFeeds() {
    $twitSrv = new TwitterService();
    print $twitSrv -> getTweets();
   }
  }

  // класс
  class TwitterService
  {
   // получает твиты
   public function getTweets() {
    // выборка токена из базы данных
    $db = new DB();
    $query = "SELECT token FROM api";
    $token = $db -> makeQuery($query);

    // авторизация посредством OAuth
    $oauth = new OAuth();
    return $oauth -> getTweetsFeed($token);
   }

  }

  class OAuth
  {
   public function getTweetsFeed( $token ) {
    // возвращает твиты, используя токен
   }
  }

  class DB
  {
   public function makeQuery() {
    // Возвращает токен из базы данных
   }
  }

?>

Здесь класс SocialFeeds зависит от класса TwitterService, который, в свою очередь, зависит от классов DB и OAuth, таким образом, и класс SocialFeeds косвенно зависит от классов DB и OAuth.

Так в чем же проблема? А проблема в том, что класс SocialFeeds зависит от конкретной реализации этих трех классов, делая невозможным, например, тестирование класса SocialFeeds как отдельную единицу. К тому же, если нам нужно будет использовать другую базу данных или провайдера OAuth, то придется искать и менять эти классы по всему коду, в котором они встречаются.

Вот здесь и становится очевидным необходимость использования механизма внедрения зависимостей (Dependency Injection, DI) в PHP. C помощью него, мы можем создавать объекты динамически, только тогда, когда это необходимо. Существуют две техники реализации этого механизма:

1) Инъекция зависимостей посредством конструктора класса. В этом приеме, зависимости объекта создаются извне и передаются конструктору класса в качестве параметра. Вот код:

<?php

  class SocialFeeds
  {
   public $tweetService;

   // в качестве парметра передается сервис Twitter
   public function __construct( TwitterService $twitService ) {
    $this -> twitService = $twitService;
   }

   // возвращает новости
   public function getSocialFeeds() {
    print $this -> twitService -> getTweets();
   }
  }

?>

Экземпляр класса TwitterService передается в качестве параметра в конструктор SocialFeeds. Несмотря на то, что класс SocialFeeds все еще зависит от сервиса TwitterService, теперь у нас есть больше свободы при выборе различных версий провайдера новостей Twitter. Подобное действие применяем и к классам DB и OAuth:

<?php

  $db = new DB();
  $oauth = new OAuth();
  $twSrv = new TwitterService( $db, $oauth );

  $sf = new SocialFeeds($twSrv);
  $sf -> getSocialFeeds();

?>

2) Инъекция зависимостей через set-метод:

<?php

  class SocialFeeds
  {
   public $tweetService;

   // set-метод для Twitter сервиса
   public function setTwitterService( TwitterService $tweetService ) {
    $this -> tweetService = $tweetService;
   }

   public function getSocialFeeds() {
    print $this -> tweetService -> getTweets();
   }

  }

  // создаем объекты
  $db = new DB();
  $oauth = new OAuth();
  $twSrv = new TwitterService();
  $sf = new SocialFeeds();

  // устанавливаем зависимости
  $twSrv -> setDb($db);
  $twSrv -> setOAuth($oauth);
  $sf -> setTwitterService($twSrv);

  // получаем новостную ленту
  $sf -> getSocialFeeds();

?>

Механизм внедрения зависимости в PHP код посредством конструктора класса, или сеттер-метода остается на выбор программиста. Однако существует негласное правило, согласно которому, через конструктор передаются такие зависимости, без которых класс не сможет функционировать, а через set-методы передаются зависимости, которые необязательны.

Таким образом, сегодня мы познакомились с тем, что такое Dependency Injection (DI) в PHP и узнали, когда его следует использовать.

Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (http://myrusakov.ru)!

Добавляйтесь ко мне в друзья ВКонтакте: http://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/rusakovmy.

Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления

Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.

Порекомендуйте эту статью друзьям:

Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

  1. Кнопка:

    Она выглядит вот так: Как создать свой сайт

  2. Текстовая ссылка:

    Она выглядит вот так: Как создать свой сайт

  3. BB-код ссылки для форумов (например, можете поставить её в подписи):

Комментарии (0):

Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.