ФорумПрограммированиеPHP для идиотов → Dependency Injection

Dependency Injection

  • master

    Сообщения: 3244 Репутация: N Группа: Джедаи

    Spritz 17 июня 2010 г. 18:20, спустя 3 часа 38 минут 49 секунд

    Очевидно, что в любом приложении есть функционально различные участки кода, и между этими участками кода есть связи (зависимости). Собственно это основное из чего приложение состоит. Обычно связи находится в коде:


    class Model {
    function run (){
    $db = mysqli(HOST, PORT); // тут мы жёстко задаём имя класса и настройки, так что если захотим что-то изменить придётся открывать код и править его, а если захотим выполнить модульный тест - то задолбаемся код менять.
    $db->query(…)
    }


    IoC (inversion of control) - это способ отделить код от связей. Связи выносятся в конфигурацию, код - в объекты. Чтобы всё работало придуманы интерфейсы.

    IoC можно реализовать по разной схеме, две из них - это DI (dependency injection) и SL (service locator).

    DI:

    interface iDB {
    function query(…);
    }

    class DB implements iDB {
    function query(…) {…}
    }

    class Model {
    function __construct (iDB $db){
    $this->db = $db;
    }

    function run (){
    $this->db->query(…);
    }
    }

    $db = new DB;
    $model = new Model($db);
    $model->run();


    SL:

    interface iDB {
    function query(…);
    }

    class DB implements iDB {
    function query(…) {…}
    }

    class Model {
    function __construct (){
    $this->db = DBManager::getDB();
    }

    function run (){
    $this->db->query(…);
    }
    }

    $model=new Model;
    $model->run();


    А "схема сборки" хранится отдельно.

    Представьте себе детский конструктор. Одинаковых деталек хуева гора, но из них можно сложить и паровоз, и самолёт, и даже трактор. Кубики одни, а схема - разная. Детальки - это объекты, схема сборки - это IoC-конфигурация, сборщик - это IoC-конвейер, программист занимается составлением схемы и выпиливанием недостающих деталек.
    не всё полезно, что в swap полезло
  • Абырвалг

    Сообщения: 6480 Репутация: N Группа: Джедаи

    Spritz 17 июня 2010 г. 23:35, спустя 5 часов 14 минут 47 секунд

    или ты имеешь в виду Registry::get('app') Registry::get('session') ?

    ни в коем случае

    class BL_Context
    {
    /**
    *
    * @var BL_Loader
    */
    protected $loader;
    /**
    *
    * @var BL_Request
    */
    protected $request;
    /**
    *
    * @var BL_Response
    */
    protected $response;
    // …
    public function __construct()
    {
    $this->request = BL_Request::instance(); // тут будет new
    $this->response = BL_Response::instance($this->request);
    $this->page = BL_Page::instance();
    // …
    }

    public function injectLoader(BL_Loader $loader)
    {
    $this->loader = $loader;
    }

    /**
    *
    * @return BL_Request
    */
    public function request()
    {
    return $this->request;
    }
    /**
    *
    * @return BL_Response
    */
    public function response()
    {
    return $this->response;
    }
    // …


    то есть что-то автоматом задается, что-то инъектится. И потом через соотв. метод достается, что бы было автодополнение (phpDoc). Ну и где-то в конфиге будет возможность задать свой класс-контекст (сомневаюсь, что кто-то будет это делать)
  • Абырвалг

    Сообщения: 6480 Репутация: N Группа: Джедаи

    Spritz 17 июня 2010 г. 23:43, спустя 8 минут 28 секунд

    с конфигами "ебется" этот же Context

Пожалуйста, авторизуйтесь, чтобы написать комментарий!