2014-10-01 47 views
0

我打算創建包含純不可變數據的類,以及訪問它的簡單特徵(或類,它不是重點)。因此,虛擬代碼來說明我的意思:通過閉包訪問私有靜態屬性 - 是否合理?

//Data class 
class DataStorage 
{ 
    use DataHandler; 

    static private $dataStorage = [ 
     'key' => 'data' 
    ]; 
} 

特質來獲取數據:

//Data getter 
trait DataHandler 
{ 
    static public function get($property) 
    { 
     $func = function() use($property) { 
      return self::$dataStorage[$property]; 
     }; 

     $obtain = Closure::bind($func, NULL, get_class()); 

     return $obtain(); 
    } 
} 

正如你所看到的,Closure用於獲取數據是私有的,它很簡單,適合我要求。但是,這種方法似乎有些危險。看起來就像我可以訪問ANY靜態私有財產ANY類。

Q1:它違背了OOP的原則嗎?

Q2:這是很好的解決方案通過使DataStorage類作爲這樣一個實現了接口,只是將其簽入DataHandler::get()方法人爲地限制這種特質的使用情況如何?

對不起,如果我的問題是愚蠢的,在這種情況下,我也非常感謝建設性的批評。

+0

那麼,你也只是可以聲明你的屬性爲公開...(假設你有一些類似的機制來設置它們)。所以,這沒有任何意義。 – bwoebi 2014-10-01 19:20:28

+0

如果你想直接訪問它,那麼沒有太多要點屬性'私人'。只需提供一個「公共」getter方法或使其本身成爲public。 – Crackertastic 2014-10-01 19:23:40

+0

我希望實際上只讀訪問它,並且我想要一種統一的機制來完成它,因爲可能會有很多'DataStorage'類。如果它只是一個getter方法,那麼可能在不存在的變量上返回self ::就會引發警告。那麼,也許我在這裏確實感到困惑...... – Nevertheless 2014-10-01 19:37:17

回答

1

我不明白您的使用封閉的論證。無論如何,你可以重寫它沒有關閉。

class DataStorage { 
    use DataHandler; 
    static private $dataStorage = [ 
     'key' => 'data' 
    ]; 
    } 

trait DataHandler { 
    static public function get($property) { 
     return self::$dataStorage[$property]; 
     } 
    } 

echo DataStorage::get('key'); 

http://3v4l.org/FOTob#v540

附:最好避免使用靜態值,它會給全局變量帶來一些缺點,如緊耦合

0

OOP可見性有助於您通過對象封裝來編寫更好的系統。這不是防彈的。

這很難但並非不可能濫用。確定的個人 可以用任何語言編寫垃圾代碼。

Allen Holub

+0

那麼爲什麼在Web上有這麼多'Closure'用法的例子,比如php.net呢?我認爲允許寫意外的敏感數據可能更多是一種濫用...... – Nevertheless 2014-10-01 20:33:50

+0

從外部修改對象的私有屬性是錯誤的。這是可能的,但錯誤的。 – Weltschmerz 2014-10-01 20:35:57

+0

這就是爲什麼我只想*以這種方式讀*數據。 – Nevertheless 2014-10-01 20:37:58