我有一个FileCopier的基类,它由资源源和资源目的地的两个" hasa "关联组成。
构造之后,FileCopier中存在三个属性:
- Source (instance of Resource)
- Destination (instance of Resource)
- Config (array of configuration stuff for this FileCopier)
我找到的所有关于这个问题的例子都是关于扩展的孩子,而不是通过组合的孩子。
我的问题是:是否有任何方法为资源实例访问它的父母的"配置"?
或者,我必须通过构造函数将对父类的引用传递给关联的子类吗?
如果我没理解错的话,你有:
class FileCopier{
/* @var Source */
private $source;
/* @var Destination */
private $destination;
/* @var Config */
private $conf;
...
}
你想从$source和$destination访问$conf吗?没有父变量或其他魔法字可以从其他两个变量访问这个$conf。最好的办法是在Resource中添加一个函数,它将设置一个本地引用到Config:
class Resource {
/* @var Config */
protected $config;
...
function setConfig(Config $config) {
$this->config = $config;
}
...
}
或者如果config设置在其他点r可能会改变,或者如果因为任何其他原因你想从你的资源中访问最新的$conf,你可以传递一个ref给FileCopier:
class Resource {
/* @var FileCopier */
protected $copier;
...
function setFileCopier(FileCopier $copier) {
$this->copier = $copier;
// and access to $this->copier->conf through a getter
// or make $conf public in FileCopier
}
...
}
那么你所要做的就是在使用$source和$destination之前调用setter。可能在FileCopier中:
class FileCopier{
...
//first case :
function setConfig($config) {
$this->config = $config;
$this->source->setConfig($config);
$this->destination->setConfig($config);
}
// Or for the second case:
function setup() {
$this->source = new Source();
$this->source->setFileCopier($this);
$this->destination = new Destination();
$this->destination->setFileCopier($this);
}
...
}
答案取决于对象的职责。
如果两个资源都是由FileCopier对象创建的,您可以通过Resource类的构造函数从FileCopier提供配置(如果所有资源都应该有配置,否则通过属性/getter&;setter)。
如果FileCopier是配置的东西,并且资源将知道当前正在使用它的FileCopier(通过构造函数或属性),那么FileCopier应该只有getConfig()或使用->config(如果属性是公共的)。
从你的命名,我有一点麻烦看到实际的用例,其中一个资源必须知道对象的配置执行任何工作的资源本身。将这部分配置(即,如果它是资源上的"save"或"move"命令)移动到实际的方法调用(并调用->save(),其中FileCopier对象使用其配置中的路径)可能会更好。
如果我对问题的理解正确的话,"父母"这个词是错误的,尽管我知道你的意思。如果对象F是一个FileCopier的实例,并且有两个属性都是instanceof Resource,那么对象F不是资源实例的父对象。我不太确定该怎么称呼这种关系:-o
你可以允许资源实例访问你的配置。在你的FileCopier类中这样做:public function setSource(Resource $r)
{
$this->Source = $r;
$r->setConfig($this->Config);
}