2009-12-29 12 views
0

我有一個通用的集合類,有各種公共的getter方法。以限制公共訪問的方式覆蓋子類中的公共方法,同時仍允許從父類訪問?

要從Collection中獲取一個項目,請調用get()。還有幾種返回多個項目的方法:getMany(),getRange(),getAll(),find(),findAll(),query(),queryAny()等。

在內部,所有這些方法返回多個項目有一個重複調用get()的循環,因爲它們聚合各個項目以返回。

一個簡單的例子:

public function get($key){ 
    return $this->collection[$key]; 
} 

public function getMany($keys){ 

    $many = array(); 

    foreach ($keys as $key){ 
     $many[] = $this->get($key); 
    } 

    return $many; 
} 

時,我想在我不希望客戶能夠從Collection訪問單個項目的方式擴展集,就會出現問題。基本上,我想禁止訪問get()方法。

我不能讓get()一個私有或受保護的函數,因爲它在父類中是公共的。

我也無法以這樣的方式重寫get(),使得它不起作用(即只用一個返回來覆蓋它,或拋出一個Exception),因爲所有其他方法都依賴於get(),並且我希望他們保持功能。

我知道我可以重寫所有依賴get()的方法來依賴一些新的受保護方法(即getOne()),但這會違反DRY原則。

什麼,我不想做的事:

class DataSet extends Collection{ 

    public function get(){ 
     throw new Exception('get() not implemented in DataSet'); 
    } 

    protected function getOne($key){ 
     return parent::get($key); 
    }  

    public function getMany($keys){ 

     $many = array(); 

     foreach ($keys as $key){ 
      $many[] = $this->getOne($key); 
     } 

     return $many; 
    } 
} 

如果我沒有上述情況,我不得不重寫了半打的方法(其中一些是相當複雜的),他們'd只與父類'方法相差幾個字符。

那麼...我還有什麼其他選擇?對於同一目標有不同的手段嗎?

回答

3

你可以做的是做一個受保護的方法說_get這可以是所有的方法在內部調用。然後,您可以在所有需要訪問的類上公開get方法,並且只需要撥打_get即可。

+0

D'oh!這是解決方案,隱藏在明顯的視野中。我所有的努力都集中在尋找子類中的解決方案 - 我沒有考慮改變父類。謝謝! – 2009-12-29 22:37:52