0

序言:設計基礎類時是否意識到並使用派生類型進行交互?我假設沒有,那麼我應該考慮以下哪種方法?對象模型設計;基類對派生類的認識


語言是PHP,但我認爲這個問題更關注的是設計模式更廣泛的主題)

我一直有一個兩難試圖一組類行事模型作爲節點;我不斷猜測我的設計決策,並導致永久的挫敗感。

鑑於這一組參數:

  • 節點具有
  • 衍生節點的任何對象類型可以是一個父母引用(單程遍歷)(或兒童)到任何其他對象類型派生的節點。

所以我有:

abstract class AbstractNode{ 

    protected $_parent; 

    public function __construct(self $parent = null){ 
     $this->_parent = $parent; 
    } 

    public function get_parent(){ 
     return $this->_parent; 
    } 

} 

class NodeOne extends AbstractNode{ } 

class NodeTwo extends AbstractNode{ } 

// more derivatives 

現在,這裏就是我的設計難題進來;遍歷期間NodeOne情況下,可能需要通過自己和衍生AbstractNode類型的任何其他實例可以發現,(注意,此功能是不是獨家NodeOne實例,但是這只是一個例子

這將使例如,針對特定類型的遍歷來聚合樹中特定類型的對象的數據。我想我會專門的方法來達到這個目的:

public function get_node_one_ancestor(){ 
    if($this->_parent instanceof NodeOne){ 
     return $this->_parent; 
    } 
    if(null !== $this->_parent){ 
     return $this->_parent->get_node_one_ancestor(); 
    } 
    return null; 
} 

由於任何派生類型可能需要遍歷實例NodeOne,它將使意義撲通在AbstractNode基類這種方法,但是現在我的基類需要了解派生類型。

我覺得這味道不好,但我不知道這種方法應該去哪裏。我正在閱讀結構設計模式以尋找可能的解決方案。


想到的一個比喻是DOM,這樣做對於某些類型的祖先穿越:

<root> 
    <foo id="1"> 
     <bar id="2"></bar> 
     <bar id="3"> 
      <foo id="4"> 
       <bar id="5"> 
        <foo id="6"> 
         <bar id="7"></bar> 
        </foo> 
       </bar> 
       <bar id="8"></bar> 
      </foo> 
     </bar> 
    </foo> 
</root> 
  • bar[@id='8']彙總所有foo祖先id值:
    結果4 1

  • bar[@id='7']合計所有foo祖先id值:
    結果6 4 1

+0

你試圖解決這個實現什麼問題?嵌套集? –

+0

否@DigitalPrecision - 它與RDBMS樹表示無關;它是一個執行樹。節點代表程序,任何給定的程序都可以調用任何其他程序。有些節點雖然具有環境屬性,並且如果執行具有環境屬性(來自示例*中的* NodeOne)的節點,則其中調用的任何節點都需要觀察該節點已更改的任何屬性,因此我需要遍歷以查找實例NodeOne'和聚合/合併屬性,然後才能完成調用。它允許一個級聯執行環境。 – Dan

+0

我明白了。我們在一個較舊的代碼庫中使用了一種節點類型的實現,但選擇不要按原來的設計移植它,因爲複雜性並不能保證它支持它的時間。 –

回答

1

你應該能夠概括它:

public function get_ancestor($type){ 
    if($this->_parent instanceof $type){ 
     return $this->_parent; 
    } 
    if(null !== $this->_parent){ 
     return $this->_parent->get_ancestor($type); 
    } 
    return null; 
} 

對我來說,好像這是有可能生活在一個外部迭代器對象,但我不能說我做了這個帖子之前給了很多想法...

+0

感謝@Matthew - 我對'$ parent'瘋狂,應該是'$ this - > _ parent' - 編輯。 – Dan

+0

再次感謝@Matthew - 我已經考慮過了,我正在重新審查其他實施細節,看看這是否合適。 – Dan