如何从依赖类中将参数传递给依赖构造函数?创建提供商?

时间:2016-04-16 23:19:34

标签: php design-patterns dependency-injection constructor design-principles

例如,我的DependentClass取决于某些AbstractCsv类。 以下是AbstractCsv工厂(http://csv.thephpleague.com/instantiation/)的声明:

public static AbstractCsv::createFromFileObject(SplFileObject $obj): AbstractCsv

以下是DependentClass构造函数的声明:

class DependentClass {
    public function __construct(AbstractCsv $csv) { /* implementation... */ }
    // implementation...
}

如您所见,要实例化AbstractCsv,我需要将SplFileObject的实例传递给依赖项的工厂函数AbstractCsv::createFromFileObject。要创建SplFileObject,我需要一个文件名。 DependentClass存储所需的文件名(例如,文件名在运行时在DependentClass内动态计算)。

如果符合以下条件,如何将AbstractCsv的实例传递到DependentClass的构造函数中:

  • 文件名在DependentClass本身
  • 中定义
  • 还要创建AbstractCsv的实例,我首先要做的 创建SplFileObject然后AbstactCsv?它是一个 恶性循环!

我目前看到打破此圈子的唯一解决方案:DependentClass不应该依赖于AbstractCsv,而应该依赖于其工厂,该工厂将提供AbstractCsvDependentClass的实例一经请求。这也将消除在SplFileObject

中创建DependentClass的需要
class DependentClass {
    public function __construct(CsvProvider $csvProvider) { /* implementation... */ }
    // implementation...
    public function someMethod($value) {
        $filename = rand($value); // somehow calculate $filename
        $csvFile = $this->csvProvider($filename);
        $csvFile->fwrite($someData);
    }
}

class CsvProvider {
    public function get(string $filename) : AbstractCsv {
        return AbstractCsv::createFromFileObject(new SplFileObject($filename));
    }
}

我认为,这个问题很常见并经常发生,对吧?我目前是DI的新手,所以我想知道:这个解决方案真的是解决这个问题的正确方法吗?这些工厂的名称是什么?我叫它provider。这是一个正确的术语吗?

0 个答案:

没有答案