【问题标题】:Class design with params and dependencies具有参数和依赖项的类设计
【发布时间】:2012-09-28 11:50:03
【问题描述】:

我在 Zend Framework 1 之后设计了我的数据库和缓存层,如下所示:

class Cache
{
    public static function create($adapter, array $params)
    {
        $class_name = 'Cache_Adapter_' . $adapter;

        return new $class_name($params);   
    }
}

abstract class Cache_Adapter
{
    public function __construct(array $params)
    {

    }
}

class Cache_Adapter_File extends Cache_Adapter
{
    // ...
}

使用示例:

// config.php
return array(
    'cache' => array(
        'adapter' => 'file',
        'params' => array(
            'path' => '/path',
        ),
    ),
);

// bootstrap.php
$dic->cache = Cache::create($config['cache']['adapter'], $config['cache']['params']);

这种方法很棒,因为每个缓存适配器可以有不同的参数, 例如,文件缓存需要存储缓存文件的目录路径。

然后我想创建用于在数据库中存储数据的缓存适配器,并意识到不是 标量参数数组,需要数据库抽象类依赖。

目前数据库连接注册在依赖注入容器中:

// config.php
return array(
    'db1' => array(
        'adapter' => 'mysql',
        'params' => array(
            'user' => 'root',
            'connect_timeout' => 5,
        ),
    ),
    'db2' => array(
        'adapter' => 'sqlsrv',
        'params' => array(
            'db' => 'foo',
        ),
    ),
);

// bootstrap.php
$dic->db1 = Site:Db::create($config['db1']['adapter'], $config['db1']['params']);
$dic->db2 = Site:Db::create($config['db2']['adapter'], $config['db2']['params']);

所以我想问一下,除了标量配置参数数组之外,如何将零个或多个特定依赖项传递给缓存适配器,这可以在 config.php 中完成。

class Cache_Adapter_Db extends Cache_Adapter
{
    // Instead of abstract Cache_Adapter::__construct(array $params)
    // something like this is needed:
    // public function __construct(array $params, Db_Adapter $db)
    public function __construct(array $params)
    {

    }
}

【问题讨论】:

    标签: php dependency-injection class-design factory


    【解决方案1】:

    涉及两个步骤:首先你的缓存适配器应该以正确的方式调用它的父类:

    class Cache_Adapter_Db extends Cache_Adapter
    {
        public function __construct(array $params, Db_Adapter $db)
        {
           parent::__construct($params);
        }
    }
    

    第二:你的工厂类Cache应该接受更多的参数:

    class Cache
    {
        public static function create($adapter, array $params, $optparams = null )
        {
            $class_name = 'Cache_Adapter_' . $adapter;
    
            return new $class_name($params, $optparams);   
        }
    }
    

    配置 php 如下所示:

    // config.php
    return array(
        'db1' => array(
            'adapter' => 'mysql',
            'params' => array(
                'user' => 'root',
                'connect_timeout' => 5,
            ),
        ),
        'db2' => array(
            'adapter' => 'sqlsrv',
            'params' => array(
                'db' => 'foo',
            ),
            'options' => 'extraoption'
        ),
    );
    

    在 bootstrap.php 中:

    $dic->db2 = Site:Db::create(
       $config['db2']['adapter'], 
       $config['db2']['params'],
       $config['db2']['options']
    );
    

    【讨论】:

    • 好的,但是在这种情况下配置数组会是什么样子?
    • 你的意思是基于数据库的缓存适配器:'options' => new Db_Adapter_Mysql(...)?这是不正确的。我需要以某种方式在配置中指定要使用的依赖项,例如'options' => 'db1',但这也不是很好,因为单个依赖项是硬编码的。如果某个适配器需要多个适配器怎么办?
    猜你喜欢
    • 1970-01-01
    • 2020-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-02
    • 2017-06-29
    相关资源
    最近更新 更多