Внедрение зависимостей простая реализация - PullRequest
4 голосов
/ 08 января 2010

после прочтения этот вопрос. Интересно, может ли кто-нибудь помочь мне понять, как правильно внедрить Dependency Injection с помощью этих классов PHP:

class DBClass
{
    private $mMysqli;
    function  __construct(mysqli $database)
    {
        $this->mMysqli=$database;
    }
    function __destruct()
    {
        $this->mMysqli->close();
    }

    public function listUsers()
    {
        $query='SELECT * FROM Utente;';
        $resultset=$this->mMysqli->query($query);
        while($row = $resultset->fetch_array(MYSQLI_ASSOC)) {
            echo $row['username'];
            echo $row['pwd'];
            echo "<br />\n";
        }

    }

    public function runQuery($query)
    {
        return $resultset=$this->mMysqli->query($query);
    }

    public function getConnection()
    {
        return $this->mMysqli;
    }
}

Класс сеанса:

class Session
{
    private $_session;
    public $maxTime;
    private $database;

    public function __construct(DBClass $database)
    {
        $this->database=$database;
        $this->maxTime['access'] = time();
        $this->maxTime['gc'] = get_cfg_var('session.gc_maxlifetime');
        session_set_save_handler(array($this,'_open'),
                array($this,'_close'),
                array($this,'_read'),
                array($this,'_write'),
                array($this,'_destroy'),
                array($this,'_clean')
                );
        register_shutdown_function('session_write_close');
        session_start();
        ...
     }
}   

Класс пользователя (для получения подробной информации о текущем вошедшем в систему пользователе):

class User
{
    private $username;
    private $role;
    private $session;

    function __construct($session)
    {
        $this->session=$session;
        ...
    }
}

Наружно:

$connection=new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_DATABASE);
$database=new DBClass($connection);
$session=new Session($database);
$user=new User($session);

Это правильный путь?

1 Ответ

9 голосов
/ 09 января 2010

Да. Теперь вы вводите зависимости через конструктор, который обеспечивает меньшую связь. Теперь вы можете легко поменять эти зависимости, например, при UnitTesting вы можете заменить их на Mocks.

У вас все еще есть некоторая связь, хотя при использовании конкретного DBClass в качестве TypeHint вместо интерфейса . Поэтому, когда вы захотите использовать другой DBClass, он должен называться DBClass. Вы могли бы добиться более слабой связи путем кодирования с интерфейсом , который вместо этого должны реализовывать конкретные классы.

Чтобы создать только отдельные экземпляры класса (как это было задано в комментариях), вы можете использовать Singleton (как предложил Кевин Пено) или Factory для создания и отслеживания того, был ли экземпляр еще создан. Или используйте DI Service Container, который похож на Factory, но не то же самое. Он создает и управляет объектами для вас.

В библиотеке Symfony Components есть контейнер внедрения зависимостей с превосходной документацией и введением в тему о том, как еще больше улучшить DI с помощью сервисных контейнеров. Контейнеры также могут быть использованы для ограничения экземпляров. Проверьте это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...