DI
DIコンテナ
サービスロケーター

DI, DIコンテナ, サービスロケーターについて

More than 1 year has passed since last update.

概要

ZendFramework2でServiceManagerを利用しているが、DI、DIコンテナ、サービスロケーター等、ある程度理解を深めたくメモ

DI(Dependency Injection)とは

DIじゃない実装

sample.php
class Sample
{
    const LOG_FILE_PATH = 'sample.log';

    private $logger = null;

    public function __construct()
    {
        $this->logger = new FileLogger();
        $this->logger->setFilePath(self::LOG_FILE_PATH);
    }

    public function doSomething()
    {
        // 何か処理
        // ログを残す
        $this->logger->info('doSomething successed!');
    }
}

外部オブジェクトを直接記載

DIな実装

sample.php
class Sample
{
    private $logger = null;

    public function __construct(LoggerInterface $logger)
    {
        $this->logger = $logger;
    }

    public function doSomething()
    {
        // 何か処理
        // ログを残す
        $this->logger->info('doSomething successed!');
    }
}

Interfaceを渡すことで実際のオブジェクトへの依存を減らしている。
他クラスが未完でも作業ができ、テスト時にモック化もできてbetter

DIコンテナとは

container.php
<?php

require_once __DIR__ . '/vendor/autoload.php';

use Pimple\Container;

use FileLogger;
use TwitterManager;
use DatabaseUserAuthenticator;
use Sample;

$container = new Container();

$container['file.logger'] = $container->protect(function($logFileName) {
    return new FileLogger($logFileName);
});

$container['twitter.manager'] = function ($c) {
    $logger = $c['file.logger']('twitter_manager.log');
    return new TwitterManager($logger);
};

$container['database.authenticator'] = function ($c) {
    return new DatabaseUserAuthenticator();
};

$container['sample'] = function ($c) {
    return new Sample($c['file.loggger']('sample.log'), $c['twitter.manager'], $c['database.authenticator']);
};

コンテナを作成してオブジェクトの生成をそこに一任する。

サービスロケーターとは

sample.php
<?php

require_once __DIR__ . '/vendor/autoload.php';

class Sample
{
    public function __construct($c)
    {
        $this->logger            = $c['file.logger']('sample.log');
        $this->sns               = $c['twitter.manager'];
        $this->userAuthenticator = $c['user.authenticator'];
    }
}

$sample = new Sample($container);

DIコンテナでは完全にコンテナにオブジェクトの生成を一任していたが
サービスロケーターではクラス内でコンテナ内のオブジェクトを探しに行っている。

参考サイト