2011-09-30 70 views
0

我有一個FileCopier的基類,它由兩個與資源和資源目標的「has-a」關聯組成。在PHP中,您可以從構成它的對象訪問父對象嗎?

施工後,三個屬性在FileCopier存在:

- Source (instance of Resource) 
- Destination (instance of Resource) 
- Config (array of configuration stuff for this FileCopier) 

的,我覺得在這個問題上的例子是所有關於通過延伸,而不是由兒童組成的兒童。

我的問題是:是否有任何方式資源實例訪問它的父母的「配置」?

或者,我是否必須通過構造函數將父對象的引用傳遞給相關的子對象?

+0

你有FileCopier和資源之間的簡單assosiation,和該協會由您定義去只有一條路(從FileCopier到資源),那麼我會說,回答你的問題是:不,你不能神奇訪問FileCopier從資源,除非你明確地通過參考。 – Deleteman

+0

不知道這是你的,但如果從資源繼承FileCopier父::的attributeName –

+0

@The_asMan家長會的工作做了什麼,而是根據他的描述,FileCopier具有類資源的兩個屬性...所以父母是行不通的,會嗎? – Deleteman

回答

0

如果我沒有理解好您有:

class FileCopier{ 
    /* @var Source */ 
    private $source; 

    /* @var Destination */ 
    private $destination; 

    /* @var Config */ 
    private $conf; 

    ... 

} 

而且你要訪問從$源和目標$ $的conf? 沒有父母或其他魔法詞從其他兩個變量中訪問此$ conf。 你最好的選擇是將函數添加到資源將設置一個本地參考配置:

class Resource { 
    /* @var Config */ 
    protected $config; 
    ... 
    function setConfig(Config $config) { 
     $this->config = $config; 
    } 
    ... 
} 

或者,如果配置設定在其他一些點r可以改變,或者如果您要訪問的任何其他原因最新$ CONF從你的資源,你可以通過一個裁判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 
    } 
    ... 
} 

然後,所有你需要做的就是使用$源和$目的地之前打電話給你的二傳手。可能在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); 
    } 

    ... 

} 

希望這會有所幫助。

+0

土狼,謝謝!我甚至沒有對Config進行分類,但是,爲什麼不呢。我認爲FileCopier->配置關聯配置的一個實例,然後傳遞給該實例的引用將是一個很好的一個。我原以爲經過FileCopier實例本身,並提供到配置公共訪問的,但我覺得作爲(在PHP中至少)它爲我提供了一種方法,更具體鍵入提示參數的配置基準本身會更清楚(而不是隻是使用數組等)。尼斯。 – Aaron

+0

嗨!樂於幫助。您不必對其進行分類,只需使用內置類型的顯式引用即可。像函數setConfig(&$配置)應該工作。 :) – Coyote

0

答案取決於你的對象的責任。

如果這兩個資源都是由FileCopier對象創建的,則可以通過Resource類的構造函數從FileCopier提供配置(如果所有資源都應該有配置 - 否則通過屬性/ getter & setter)。

如果FileCopier是配置好的東西,Resources會知道它當前正在使用的FileCopier(通過構造函數或屬性),那麼FileCopier應該只有一個getConfig()或者使用 - >配置如果屬性是公共的。

從您的命名,我有一點看到實際使用情況下的資源必須知道執行對資源本身的任何工作對象的配置的麻煩。這可能是更更好的移動配置的那部分(即,如果它是一個「保存」或「移動」命令的資源)的實際方法調用(和調用 - >保存()在FileCopier對象使用從路徑的配置

+0

謝謝。資源具有URI對象,一個臨時文件,和後者的接口ProtocolAdapter所以可在用於在URI的「方案」所代表的各種協議的支持下降的適配器。我最大的問題是與需要它的孩子分享配置。我想我會採取halfer的建議並將配置傳遞給Resource的構造函數。 「配置」是耦合最大的問題。從很多OOP程序員發佈的問題來看,我可以看到我不是唯一的。 – Aaron

0

如果我已經正確地理解了這個問題,但「parent」是錯誤的術語,但我知道你的意思如果一個對象F是FileCopier的一個實例,並且有兩個屬性都是instanceof Resource,那麼對象F不是資源實例的父對象,不太確定這個關係是什麼,tbh:-o

雖然你可以允許資源實例訪問你的配置,但在你的FileCopier類中做這樣的事情:

public function setSource(Resource $r) 
{ 
    $this->Source = $r; 
    $r->setConfig($this->Config); 
} 

這樣可以透明地「通知」配置資源。

+1

halfer,謝謝。我相信這種關係通常被稱爲「協會」或「有-A」。我有一個設計模式書建議贊成「構圖」而不是繼承。對象由關聯組成,並通過繼承進行擴展。我希望我寫這個;) – Aaron

+0

沒問題。是的,在你的用例中,繼承不正確。在我看來,一個得到通過具有在過去使用這種方法來學習這種困難的方式,然後發現的類需要從兩個父母繼承! – halfer