2012-11-16 62 views
0

考慮下面的類結構:可繼承數組的設計模式?

class Foo { 
    protected static $_things = ['thing']; 
} 

class Bar extends Foo { 
    protected static $_things = [ 
     'thing', 'other-thing' 
    ]; 
} 

class Baz extends Bar { 
    protected static $_things = [ 
     'thing', 'other-thing', 'something-else' 
    ]; 
} 

class Quux extends Baz { 
    // Note the lack of "other-thing" 
    protected static $_things = [ 
     'thing', 'something-else', 'one-more' 
    ]; 
} 

什麼是重構這一點,並保持數組元素越乾的最好方法?例如,「東西」元素應該只定義一次(在Foo),「其他東西」元素應該只定義一次(在Bar)等等。

實際上,這個數組非常大,有時候可能會有多達4或5個級別的繼承,每個需要以某種特殊方式「修改」這個數組,無論是添加還是刪除元素。

我一直在玩的初始化方法的想法,將做適當的修改,但想看看是否有任何更好的方法第一。

回答

2

簡單的解決方案,我能想到的(主要基於Singleton模式)。

我不認爲有任何編譯時的方式來做你正在尋找的東西。

<?php 
class A { 
    private static $a = [1, 2, 3]; 
    public static function getA() { 
     return self::$a; 
    } 
} 

class B extends A { 
    private static $a = null; 
    public static function getA() { 
     if (self::$a === null) 
      self::$a = array_merge(A::getA(), [4, 5, 6]); 
     return self::$a; 
    } 
} 

echo join(',', B::getA()) . "\n"; 
+0

感謝您的建議。這實際上與我一直在玩的東西非常相似,只是我在構造函數中進行了合併而不是getter。 – FtDRbwLXw6

-1

也許這樣的事情會工作:

class Foo { 
    protected static $_things = ['thing']; 
} 

class Bar extends Foo { 
    protected static $_things = array_merge($_things, ['other-thing']); 
} 

//and so on... 
+0

狀態不行,PHP不會讓任何東西比靜態清晰度文字其他(實際上,它甚至不會* PARSE *它)。 –

0

判斷不確切地知道用例有點難,但繼承似乎是錯誤的方法。 無論如何,您需要將數據的存儲方式和訪問方式分開,即將數據結構從數據模型中分離出來。

最好的解決方案是創建一個單獨的列表類並在多個客戶端中使用它。例如是這樣的:

class SomeList{ 
    private $_things = ['thing']; 
    function mergeItems($items){ 
     //merge the $this->_things and $items arrays uniquely 
     //... 
    } 
} 

class Foo{ 
    private $list; 

    function __construct($list){ 
     $this->list = $list; 
     $this->list->mergeItems(['thing', 'other-thing']); 
    } 
} 

你不應該保存在靜態屬性

+0

謝謝你的回覆,但該屬性不存儲狀態。每個類都有一個可接受元素的常量/不可變數組。一旦他們初始化,他們永遠不會改變。我遇到的問題是1)PHP沒有任何方法來定義一個不可變數組,2)我想保持數據乾燥。我現在只是重寫每個類中的數組,並重復父類的數組中的相關元素。這很好,但維護起來很痛苦,因爲修改基類中的一個元素需要修改每個子類。 – FtDRbwLXw6

+0

如果數據是不可變的,那麼你就有更多的理由來封裝數組並避免突變。顯然,列表客戶端可以靜態存儲列表實例,如果這是你最想要的。然而,你需要問自己,它是否真的有必要是靜態的。 (還有繼承是否有必要,繼承只是很少的保證,繼承鏈幾乎總是非常糟糕的代碼味道) – Creynders