例如,我的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
,而应该依赖于其工厂,该工厂将提供AbstractCsv
到DependentClass
的实例一经请求。这也将消除在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
。这是一个正确的术语吗?